notifyAll()调用时,并非唤醒所有的等待线程,而是当nofityAll()因某个特定锁而被调用时,只有等待这个锁的任务才会被唤醒。
class Blocker{ synchronized void waitingCall(){ try { while(!Thread.interrupted()){ wait(); System.out.println(Thread.currentThread()+" "); } } catch (InterruptedException e) { //Ok to exit this way } } synchronized void prod(){ notify(); } synchronized void prodAll(){ notifyAll(); } } class Task implements Runnable{ static Blocker blocker=new Blocker(); @Override public void run() { blocker.waitingCall(); } } class Task2 implements Runnable{ static Blocker blocker=new Blocker(); @Override public void run() { blocker.waitingCall(); } } public class NotifyVsNotifyAll { public static void main(String[] args) throws Exception{ ExecutorService exec= Executors.newCachedThreadPool(); for(int i=0;i<5;i++) exec.execute(new Task()); exec.execute(new Task2()); Timer timer=new Timer(); timer.scheduleAtFixedRate(new TimerTask() { boolean prod=true; @Override public void run() { if(prod){ System.out.println("\nnotify()"); Task.blocker.prod(); prod=false; }else{ System.out.println("\nnotifyAll() "); Task.blocker.prodAll(); prod=true; } } },400,400); TimeUnit.SECONDS.sleep(5); timer.cancel(); System.out.println("\nTimer canceled"); TimeUnit.MILLISECONDS.sleep(500); System.out.println("Task2.blocker.prodAll()"); Task2.blocker.prodAll(); TimeUnit.MILLISECONDS.sleep(500); System.out.println("\nShutting down"); exec.shutdown(); } }Task和Task2每个都有自己的Blocker对象,因此每个Task对象都会在Task.blocker上阻塞,而每个Task2都会在Task2.blocker上阻塞。