Lock.Condition可以实现唤醒一部分线程(针对某种操作的线程)。
如果特定资源只有生产者和消费者两种线程操作,则Condition并没有多大意义。produce和consume之间相互切换,直接用wait和nofity即可。
但如果有超过两种以上的操作对应不同线程,则Condition的多路等待特性就会非常有意义。
假定有一个资源类,有三个方法m1, m2, m3, 这三个方法都是要将从1到99写入一个List. 现在要求用三个线程按固定顺序轮流写入1-99. 线程A写入1,线程B写入2,线程C写3......线程A写入97,线程B写入98,线程C写入99,然后结束。
class Resource {
private Lock lock = new ReentrantLock();
private Condition c1 = lock.newCondition();
private Condition c2 = lock.newCondition();
private Condition c3 = lock.newCondition();
private volatile int turn = 1;
private List<Integer> data = new ArrayList<>();
private volatile int i = 0;
private void add(int i) {
System.out.println(Thread.currentThread().getName() + " add: " + i);
data.add(i);
}
public void m1() throws InterruptedException {
lock.lock();
try {
while (i < 98) {
while (turn != 1) {
c1.await();
}
if (i < 97)
add(++i);
turn = 2;
c2.signal();
}
} finally {
lock.unlock();
}
}
public void m2() throws InterruptedException {
lock.lock();
try {
while (i < 99) {
while (turn != 2) {
c2.await();
}
if (i < 98)
add(++i);
turn = 3;
c3.signal();
}
} finally {
lock.unlock();
}
}
public void m3() throws InterruptedException {
lock.lock();
try {
while (i < 100) {
while (turn != 3) {
c3.await();
}
if (i == 99) break;
add(++i);
turn = 1;
c1.signal();
}
} finally {
lock.unlock();
}
}
}
这个类中,三个方法分别对应三个线程的操作。
以下是测试类:
public class Main {
public static void main(String[] args) {
Resource r = new Resource();
Thread a = new Thread(() -> {
try {
r.m1();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread b = new Thread(() -> {
try {
r.m2();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread c = new Thread(() -> {
try {
r.m3();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
a.start();
b.start();
c.start();
}
}
输出: 可以看到三个线程轮流写入1-99.
Thread-0 add: 1
Thread-1 add: 2
Thread-2 add: 3
Thread-0 add: 4
Thread-1 add: 5
Thread-2 add: 6
Thread-0 add: 7
Thread-1 add: 8
Thread-2 add: 9
Thread-0 add: 10
Thread-1 add: 11
Thread-2 add: 12
Thread-0 add: 13
Thread-1 add: 14
Thread-2 add: 15
Thread-0 add: 16
Thread-1 add: 17
Thread-2 add: 18
Thread-0 add: 19
Thread-1 add: 20
Thread-2 add: 21
Thread-0 add: 22
Thread-1 add: 23
Thread-2 add: 24
Thread-0 add: 25
Thread-1 add: 26
Thread-2 add: 27
Thread-0 add: 28
Thread-1 add: 29
Thread-2 add: 30
Thread-0 add: 31
Thread-1 add: 32
Thread-2 add: 33
Thread-0 add: 34
Thread-1 add: 35
Thread-2 add: 36
Thread-0 add: 37
Thread-1 add: 38
Thread-2 add: 39
Thread-0 add: 40
Thread-1 add: 41
Thread-2 add: 42
Thread-0 add: 43
Thread-1 add: 44
Thread-2 add: 45
Thread-0 add: 46
Thread-1 add: 47
Thread-2 add: 48
Thread-0 add: 49
Thread-1 add: 50
Thread-2 add: 51
Thread-0 add: 52
Thread-1 add: 53
Thread-2 add: 54
Thread-0 add: 55
Thread-1 add: 56
Thread-2 add: 57
Thread-0 add: 58
Thread-1 add: 59
Thread-2 add: 60
Thread-0 add: 61
Thread-1 add: 62
Thread-2 add: 63
Thread-0 add: 64
Thread-1 add: 65
Thread-2 add: 66
Thread-0 add: 67
Thread-1 add: 68
Thread-2 add: 69
Thread-0 add: 70
Thread-1 add: 71
Thread-2 add: 72
Thread-0 add: 73
Thread-1 add: 74
Thread-2 add: 75
Thread-0 add: 76
Thread-1 add: 77
Thread-2 add: 78
Thread-0 add: 79
Thread-1 add: 80
Thread-2 add: 81
Thread-0 add: 82
Thread-1 add: 83
Thread-2 add: 84
Thread-0 add: 85
Thread-1 add: 86
Thread-2 add: 87
Thread-0 add: 88
Thread-1 add: 89
Thread-2 add: 90
Thread-0 add: 91
Thread-1 add: 92
Thread-2 add: 93
Thread-0 add: 94
Thread-1 add: 95
Thread-2 add: 96
Thread-0 add: 97
Thread-1 add: 98
Thread-2 add: 99
网友评论