/** * 三个线程,线程A不停打印A、线程B不停的打印B、线程C不停的打印C, * 如何通过synchronized、wait、notifyAll(或notify)的组合,使三个线程不停地且顺序地打印出ABCABC */ public class ABCRunnable implements Runnable { private String obj; //前一个线程需要释放,本线程需要wait的锁 private Object prev; //本线程需要释放,下一个线程需要wait的锁 private Object self; public ABCRunnable(String obj, Object prev, Object self) { this.obj = obj; this.prev = prev; this.self = self; } @Override public void run() { int i = 3; while (i > 0) { //为了在控制台好看到效果,我这里打印3轮 synchronized (prev) { //抢前面线程的锁 synchronized (self) {// 抢到自己应该释放的锁 System.out.println(obj); i--; self.notifyAll(); //唤醒其他线程抢self }//释放自己应该释放的锁 try { //走到这里本线程已经释放了自己应该释放的锁,接下来就需要让自己需要等待的锁进行等待就可以了 if (i > 0) { //我最开始没加这个条件,但是测试发现程序没停,其实分析一下就可以知道 //当前面i--使i=0了,其实该线程就已经完成3次打印了,就不需要再等前面的锁了 //因此这里加了该if判断 prev.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException { Object lockA = new Object(); Object lockB = new Object(); Object lockC = new Object(); //线程A需要等待C线程释放的锁,同时需要释放本线程该释放的锁A new Thread(new ABCRunnable("A", lockC, lockA)).start(); Thread.sleep(1); //确保开始时A线程先执行 //线程B需要等待A线程释放的锁,同时需要释放本线程该释放的锁B new Thread(new ABCRunnable("B", lockA, lockB)).start(); Thread.sleep(1); //确保开始时B线程第2个执行 //线程C需要等待B线程释放的锁,同时需要释放本线程该释放的锁C new Thread(new ABCRunnable("C", lockB, lockC)).start(); } }