方式一:使用wait()和notifyAll()
public class demo1 {private int n = 0;private int turn = 0;public static void main(String[] args) {new demo1().startThreads();}private void startThreads() {new Thread(() -> printLetter('A', 0), "线程1").start();new Thread(() -> printLetter('B', 1), "线程2").start();new Thread(() -> printLetter('C', 2), "线程3").start();}private synchronized void printLetter(char letter, int target) {while (n <= 100) {while (turn != target) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}if (count > 100) {System.exit(0);}System.out.println("第" + n++ + "个:" + letter);turn = (turn + 1) % 3;notifyAll();}}
}
方式二:使用Lock和Condition
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class demo2 {private int n = 0;private int turn = 0;private final Lock lock = new ReentrantLock();private final Condition condition = lock.newCondition();public static void main(String[] args) {new demo2().startThreads();}void startThreads() {new Thread(() -> printLetter('A', 0)).start();new Thread(() -> printLetter('B', 1)).start();new Thread(() -> printLetter('C', 2)).start();}private void printLetter(char letter, int target) {lock.lock();try {while (n <= 100) {while (turn != target) {condition.await();}if (n > 100) {System.exit(0);}System.out.println("第" + n++ + "个线程:" + letter);turn = (turn + 1) % 3;condition.signalAll();}} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}}
方式三:使用CyclicBarrier循环栅栏
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicInteger;public class demo3 {private final CyclicBarrier cyclicBarrier = new CyclicBarrier(3);private final AtomicInteger count = new AtomicInteger(0);private int turn = 0;public static void main(String[] args) {new demo3().startThreads();}private void startThreads() {new Thread(() -> printLetter('A', 0), "线程1").start();new Thread(() -> printLetter('B', 1), "线程2").start();new Thread(() -> printLetter('C', 2), "线程3").start();}private void printLetter(char letter, int target) {try {while (count.get() <= 100) {while (turn != target) {cyclicBarrier.await();}System.out.println("第" + count + "个线程:" + letter);if (count.getAndIncrement() == 100) {System.exit(0);}turn = (turn + 1) % 3;}} catch (BrokenBarrierException | InterruptedException e) {e.printStackTrace();}}
}
流程演示:
第一轮:
- turn=0,线程一符合条件,线程二await(),线程三await();
- 进行打印,count++,turn加1取3的余数,此时turn=1;
- 线程一await(),释放栅栏;
第二轮:
- turn=1,线程二符合条件,线程一await(),线程三await();
- 进行打印,count++,turn加1取3的余数,此时turn=2;
- 线程二await(),释放栅栏;
第三轮:
- turn=2,线程三符合条件,线程一await(),线程二await();
- 进行打印,count++,turn加1取3的余数,此时turn=0;
- 线程三await(),释放栅栏;
循环至count=100......
ps:以下是我整理的java面试资料,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!
链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java面试宝典》