Lock锁的多线程通信

根据jdk对Lock接口的描述,Lock实现提供比使用synchronized方法和语句可以获得的更广泛的锁定操作。 它们允许更灵活的结构化,可能具有完全不同的属性,并且可以支持多个相关联的对象Condition

synchronized是Java的一个关键字,而Lock是一个接口。Lock锁是一种比synchronized关键字更加灵活的锁,在线程通信中,synchronized锁在线程通信中有wait(阻塞线程,释放锁)和notisfy(随机唤醒一个线程)和notisfyAll(唤醒所有线程)三个方法。在线程通信中不能指定唤醒某一个线程,只能将所有线程都唤醒都进行判断,再决定那个线程运行下去,这样在很多情形下都会造成资源的浪费,形成不必要的开销。而lock锁提供的api可以单独指定某个线程唤醒,这样在对线程的执行流程有规定的情形下,比用synchronized关键字更加灵活和实用。

例如下列情形:三个线程,要求线程一打印1-5五个数,之后线程2打印1-10十个数,线程 3打印1-15十五个数,之后线程一打印5个数,线程二打印10个数。。。。。。循环5个循环。

应用Lock锁进行线程通信的方法:

 1 import java.util.concurrent.locks.Condition;
 2 import java.util.concurrent.locks.Lock;
 3 import java.util.concurrent.locks.ReentrantLock;
 4 
 5 public class Print_01 {
 6     public static void main(String[] args) {
 7         Print print = new Print();
 8         new Thread(()->{
 9             for (int i=0;i<5;i++) {
10                 print.print5();
11             }
12         },"A线程").start();
13         new Thread(()->{
14             for (int i=0;i<5;i++) {
15                 print.print10();
16             }
17         },"B线程").start();
18         new Thread(()->{
19             for (int i=0;i<5;i++) {
20                 print.print15();
21             }
22         },"C线程").start();
23     }
24 }
25 class Print{
26     private int count=3;
27     //使用lock锁
28     Lock lock=new ReentrantLock();
29     Condition conditio1=lock.newCondition();  //一把钥匙
30     Condition conditio2=lock.newCondition();  //一把钥匙
31     Condition conditio3=lock.newCondition();  //一把钥匙
32 
33     public void print5(){
34         lock.lock();
35         try {
36             //判断
37             while(count!=1){
38                 conditio1.await();
39             }
40             //干活
41             for (int i = 1; i <=5; i++) {
42                 System.out.print(Thread.currentThread().getName()+i);
43                 System.out.println();
44             }
45             //通知
46             count=2;
47             conditio2.signal();
48         } catch (Exception e) {
49             e.printStackTrace();
50         } finally {
51             lock.unlock();
52         }
53     }
54 
55     public void print10(){
56         lock.lock();
57         try {
58             //判断   多线程下的判断必须要用while,线程唤醒后要再次判断,否则会造成虚假唤醒(三个线程及以上就会出问题)
59             while(count!=2){
60                 conditio2.await();
61             }
62             //干活
63             for (int i = 1; i <=10; i++) {
64                 System.out.print(Thread.currentThread().getName()+i);
65                 System.out.println();
66             }
67             //通知
68             count=3;
69             conditio3.signal();
70         } catch (Exception e) {
71             e.printStackTrace();
72         } finally {
73             lock.unlock();
74         }
75     }
76     public void print15(){
77         lock.lock();
78         try {
80             while(count!=3){
81                 conditio3.await();
82             }
84             for (int i = 1; i <=15; i++) {
85                 System.out.print(Thread.currentThread().getName()+i);
86                 System.out.println();
87             }
89             count=1;
90             conditio1.signal();
91         } catch (Exception e) {
92             e.printStackTrace();
93         } finally {
94             lock.unlock();
95         }
96     }
97 }

猜你喜欢

转载自www.cnblogs.com/fangtingfei/p/12008501.html