多线程打印01 02 03 04 05 ...
多线程打印01 02 03 04 05 ...
原文:https://www.cnblogs.com/hapjin/p/17501458.html
多线程打印:01 02 03 04 05 ...
- main 函数中的while(true)表示线程会一直争抢锁,进行打印
- 通过检查条件变量是否满足,来决定打印0、还是打印奇数、还是打印偶数
- volatile 变量enableOdd 在打印0之后,进行切换:决定打印奇数 or 打印偶数
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.IntConsumer;
/**
* @date 2022/6/5
* 打印 01 02 03 04 05 06 ...
*/
public class ZeroEvenOdd {
private static IntConsumer intConsumer = x -> System.out.println(x);
private ReentrantLock lock = new ReentrantLock();
private Condition zeroCondition = lock.newCondition();
private Condition oddCondition = lock.newCondition();
private Condition evenCondition = lock.newCondition();
private volatile boolean printZero = true;
private volatile boolean printOdd = false;
private volatile boolean printEven = false;
//控制下一次是打印奇数,还是打印偶数
private volatile boolean enableOdd = false;
public static void main(String[] args) {
ZeroEvenOdd zeroEvenOdd = new ZeroEvenOdd();
Thread t1 = new Thread(() -> {
while (true) {
try {
zeroEvenOdd.zero();
sleep(1);
} catch (Exception e) {
}
}
});
Thread t2 = new Thread(() -> {
int i = 1;
//while 循环
while (true) {
try {
zeroEvenOdd.even(i += 2);
sleep(1);
} catch (InterruptedException e) {
System.out.println(e);
}
}
});
Thread t3 = new Thread(() -> {
int i = 2;
while (true) {
try {
zeroEvenOdd.odd(i += 2);
sleep(1);
} catch (InterruptedException e) {
System.out.println(e);
}
}
});
t1.start();
t2.start();
t3.start();
}
// printNumber.accept(x) outputs "x", where x is an integer.
public void zero() throws InterruptedException {
try {
lock.lock();
while (!printZero) {
zeroCondition.await();
}
//若不赋值为false,main方法while true循环可能再次由此线程抢到锁,会导致重复连续打印2个0
printZero = false;
intConsumer.accept(0);
if (enableOdd) {
//打印偶数
printOdd = true;
//下一次打印奇数
enableOdd = false;
//通知偶数打印
oddCondition.signal();
}else {
printEven = true;
enableOdd = true;
evenCondition.signal();
}
} finally {
lock.unlock();
}
}
public void even(int i) throws InterruptedException {
try {
lock.lock();
while (!printEven) {
evenCondition.await();
}
//已经打印了奇数,下一个打印不能是奇数,这里必须显示赋值为false,避免此线程下一次又抢到了锁,造成重复打印2个奇数
printEven = false;
intConsumer.accept(i);
//
printZero = true;
zeroCondition.signal();
} finally {
lock.unlock();
}
}
public void odd(int i) throws InterruptedException {
try {
lock.lock();
while (!printOdd) {
oddCondition.await();
}
printOdd = false;
intConsumer.accept(i);
printZero = true;
zeroCondition.signal();
} finally {
lock.unlock();
}
}
private static void sleep(long sec) {
try {
TimeUnit.SECONDS.sleep(sec);
} catch (InterruptedException e) {
System.out.println(e);
}
}
}
学习使我充实,分享给我快乐!