两个线程循环输出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;
public class ConcurrentTest {
@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"); } } }); } }
|