两个线程交替输出1-100的奇偶数

两个线程循环输出1-100,一个输出奇数,一个输出偶数

可以用Condition去实现这个功能。开启两个线程去获取同一个可重入锁.获取到锁之后打印当前的值,再使用condition.signal()唤醒另一个线程,然后自己condition.await()。最后释放锁。两个线程使用同样的代码。每次只有一个线程运行进行来实现交替输出

直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import org.jooq.lambda.Unchecked;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.RepeatedTest;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author xyz327
* @date 2021/5/30 16:13
*/
public class ConcurrentTest {

/**
* 两个线程循环输出1-100,一个输出奇数,一个输出偶数
*/
@RepeatedTest(1000)
void eachExc() throws Exception {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
CountDownLatch countDownLatch = new CountDownLatch(2);
AtomicInteger count = new AtomicInteger(1);
List<Integer> resultA = new ArrayList<>();
List<Integer> resultB = new ArrayList<>();
new Thread(Unchecked.runnable(() -> {
while (true) {
lock.lock();
try {
if (count.get() > 100) {
countDownLatch.countDown();
condition.signal();
return;
}
int value = count.getAndIncrement();
resultA.add(value);
condition.signal();
condition.await();
} finally {
lock.unlock();
}
}
}), "A").start();
new Thread(Unchecked.runnable(() -> {
while (true) {
lock.lock();
try {
if (count.get() > 100) {
countDownLatch.countDown();
condition.signal();
return;
}
int value = count.getAndIncrement();
resultB.add(value);
condition.signal();
condition.await();
} finally {
lock.unlock();
}
}
}), "B").start();

countDownLatch.await();

System.out.println(resultA);
System.out.println(resultB);
// 校验结果是否正确
Assertions.assertEquals(resultA.size(), 50);
Assertions.assertEquals(resultB.size(), 50);
boolean isAOdd = resultA.get(0) % 2 != 0;
Assertions.assertAll(() -> {
for (Integer integer : resultA) {
boolean isOdd = integer % 2 != 0;
if(isAOdd && !isOdd){
throw new IllegalArgumentException("A");
}
}

for (Integer integer : resultB) {
boolean isOdd = integer % 2 != 0;
if(isAOdd && isOdd){
throw new IllegalArgumentException("B");
}
}
});
}
}