根据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 }