1:锁(Lock) 1.1 java提供了一个锁的接口,这个锁同样可以达到同步代码块的功能,API文档上说使用锁比使用synchronized更加灵活。 1.2 如何使用这个“锁&am ...
1:锁(Lock)
1.1 java提供了一个锁的接口,这个锁同样可以达到同步代码块的功能,API文档上说使用锁比使用synchronized更加灵活。
1.2 如何使用这个“锁”
//1.创建一个所对象,我们可以理解为写一个synchronized代码块
public static Lock lock = new ReentrantLock();//用lock的一个子类去创建
//2.假设有某程序中使用两把锁,这两把锁是类似于synchronized里的锁
//要使用到Condition类,中文:条件、情况、制约、限制的意思,在API文档总称之为“条件、条件列队或者条件变量”
public static Condition notFull = lock.newCondition();//Condition
public static Condition notEmpty = lock.newCondition();
1.3 Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,Condition 替代了 Object 监视器方法的使用。(摘自文档,重点是最后一句)
1.4 重要方法(Condition的):
await():等候,调用此方法线程将释放锁,进入等待状态
signal():中文:信号、发信号。调用此方法可以唤醒一个等待总的线程
signalAll():唤醒所有在等待重点的线程
1.5 使用Lock和Condition的生产和消费的代码。
1 package com.java.lock; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.concurrent.locks.Condition; 6 import java.util.concurrent.locks.Lock; 7 import java.util.concurrent.locks.ReentrantLock; 8 9 public class ProduceCustomerDemo1 { 10 11 public static void main(String[] args) { 12 Produce p1 = new Produce(); 13 p1.setName("生产者1"); 14 Produce p2 = new Produce(); 15 p2.setName("生产者2"); 16 Produce p3 = new Produce(); 17 p3.setName("生产者3"); 18 Customer c1 = new Customer(); 19 c1.setName("消费者1"); 20 Customer c2 = new Customer(); 21 c2.setName("消费者2"); 22 Customer c3 = new Customer(); 23 c3.setName("消费者3"); 24 p1.start(); 25 p2.start(); 26 c1.start(); 27 c2.start(); 28 p3.start(); 29 c3.start(); 30 } 31 } 32 33 class MyLock { 34 public static Lock lock = new ReentrantLock(); 35 public static Condition notFull = lock.newCondition(); 36 public static Condition notEmpty = lock.newCondition(); 37 public static int num;// 编号 38 public static int sum;// 库存 39 public static Object obj = new Object(); 40 public static List<Integer> list = new ArrayList<Integer>(); 41 } 42 43 class Produce extends Thread { 44 @Override 45 public void run() { 46 while (true) { 47 //同步开始的标志,这里代替了synchronized 48 MyLock.lock.lock(); 49 while (MyLock.sum >= 6) {// 在多个消费者操作这个数据时,每次都要判断而且是循环判断 50 try { 51 //notFull,调用await()方法进入等待状态,前提是sum》=6 52 MyLock.notFull.await(); 53 } catch (InterruptedException e) { 54 e.printStackTrace(); 55 } 56 } 57 58 MyLock.sum++; 59 MyLock.num++; 60 MyLock.list.add(MyLock.num); 61 try { 62 Thread.sleep(100); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 System.out.println(Thread.currentThread().getName() + "生产了一个产品,编号:" 67 + MyLock.num + ",现有:" + MyLock.sum + "个"); 68 //调用signal()方法将等待中的线程唤醒,也可以使用signalAll()方法 69 MyLock.notEmpty.signal(); 70 //同步结束的标志 71 MyLock.lock.unlock(); 72 } 73 } 74 } 75 76 class Customer extends Thread { 77 78 @Override 79 public void run() { 80 while (true) { 81 //同步代码块开始 82 MyLock.lock.lock(); 83 while (MyLock.sum == 0) { 84 try { 85 //进入线程等待状态,前提是sum==0 86 MyLock.notEmpty.await(); 87 } catch (InterruptedException e) { 88 e.printStackTrace(); 89 } 90 } 91 int ran = (int) (Math.random() * MyLock.sum); 92 MyLock.sum--; 93 try { 94 Thread.sleep(100); 95 } catch (InterruptedException e) { 96 e.printStackTrace(); 97 } 98 int number = MyLock.list.remove(ran); 99 System.out.println(Thread.currentThread().getName() + "消费了一个包子,编号:"100 + number + ",现有:" + MyLock.sum + "个");101 //唤醒等待中的一个线程102 MyLock.notFull.signal();103 //同步代码块结束104 MyLock.lock.unlock();105 }106 }107 108 }
海外公司注册、海外银行开户、跨境平台代入驻、VAT、EPR等知识和在线办理:https://www.xlkjsw.com
原标题:Java多线程(三)锁对象和线程池
关键词:JAVA
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。