我们知道,线程的
等待/通知机制会随机唤醒一个正在等待的线程或者全部唤醒,无法控制线程的顺序调度. wait/notify(notifyAll)无法控制线程的调度顺序,但是如果我们利用好await/single(singleAll)的话,可以实现线程的顺序调度
我们下面以一个需求来学习如何用await/single(singleAll)来实现线程的顺序调度
需求:
同时启动三个线程,并且A线程打印5次,B线程打印10次,C线程打印15次,循环打印3遍.
代码实现
1package com.atguigu.juc.MyLock;
2
3import java.util.concurrent.locks.Condition;
4import java.util.concurrent.locks.Lock;
5import java.util.concurrent.locks.ReentrantLock;
6
7class State {
8 private int number = 1;
9 private Lock lock = new ReentrantLock();
10 private Condition c1 = lock.newCondition();
11 private Condition c2 = lock.newCondition();
12 private Condition c3 = lock.newCondition();
13
14 public void print5 () {
15 lock.lock();
16 try {
17 while (number != 1) {
18 c1.await();
19 }
20 for (int i = 0; i < 5; i++) {
21 System.out.println(Thread.currentThread().getName() + "\t" + i);
22 }
23 number = 2;
24 c2.signal();
25 } catch (Exception e) {
26 e.printStackTrace();
27 } finally {
28 lock.unlock();
29 }
30 }
31
32 public void print10 () {
33 lock.lock();
34 try {
35 while (number != 2) {
36 c2.await();
37 }
38 for (int i = 0; i < 10; i++) {
39 System.out.println(Thread.currentThread().getName() + "\t" + i);
40 }
41 number = 3;
42 c3.signal();
43 } catch (Exception e) {
44 e.printStackTrace();
45 } finally {
46 lock.unlock();
47 }
48 }
49
50 public void print15 () {
51 lock.lock();
52 try {
53 while (number != 3) {
54 c3.await();
55 }
56 for (int i = 0; i < 15; i++) {
57 System.out.println(Thread.currentThread().getName() + "\t" + i);
58 }
59 number = 1;
60 c1.signal();
61 } catch (Exception e) {
62 e.printStackTrace();
63 } finally {
64 lock.unlock();
65 }
66 }
67
68}
69
70public class ConditionDemo {
71
72 public static void main(String[] args) {
73 State state = new State();
74 new Thread(() -> {
75 for (int i = 0; i < 3; i++) {
76 state.print5();
77 }
78 ;
79 }, "A").start();
80
81 new Thread(() -> {
82 for (int i = 0; i < 3; i++) {
83 state.print10();
84 }
85
86 }, "B").start();
87
88 new Thread(() -> {
89 for (int i = 0; i < 3; i++) {
90 state.print15();
91 }
92
93 }, "C").start();
94 }
95
96}
总结: 运用await/single(singleAll)的使用特点, 实例化多个Condition对象可以实现线程的顺序调度.