1. - waiting on <lock id> —— 对应java.lang.Thread.State: WAITING
表示线程执行到了锁的wait()方法上
由于wait()方法会释放锁,所以当前线程此时处于未获取锁状态,等待notify() || notifyAll()
2. - waiting to lock <lock id> —— 对应java.lang.Thread.State: BLOCKED
表示锁已经被其他线程占有,该线程只能进入阻塞状态等待该锁的持有者释放锁再竞争
notify ():
从等待指定对象(调用notify的对象)的锁的线程中随机选取一个线程执行,其他线程状态仍然为waiting on
如果被选中的线程没有再执行notify或者notifyAll,这些线程可能永远处在waiting on状态
notifyAll() :
通知所有在等待指定对象的锁的线程退出waiting on状态
进入waiting to lock状态去参与锁的竞争
实例1:生产者与消费者模式
创建共享变量
public class VarHolder {
private boolean needWait = true;
public synchronized void doConsumer() {
while (needWait) {
try {
System.out.println(Thread.currentThread().getName() + " is going to wait()");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
needWait = true;
System.out.println(Thread.currentThread().getName() + " get Notified");
}
public synchronized void doProduce() {
while (!needWait) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
needWait = false;
notify();
// notifyAll();
}
}
创建生产者和消费者
public class Producer implements Runnable { private VarHolder holder; public Producer(VarHolder holder) { this.holder = holder; } @Override public void run() { holder.doProduce(); } }
public class Consumer implements Runnable { private VarHolder holder; public Consumer(VarHolder holder) { this.holder = holder; } @Override public void run() { holder.doConsumer(); } }
创建测试类
public class TestNotify { public static void main(String[] args) { VarHolder holder = new VarHolder(); //启动两个消费者,一个生产者 for (int i = 0; i < 2; i++) { new Thread(new Consumer(holder), "consumer-" + i).start(); } //等待1s让consumer线程都进入wait()方法 try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new Producer(holder), "producer1").start(); } }
分别注释notify()和notifyAll()查看运行结果:
doProduce()执行notify()的结果: 仅仅唤醒一个线程
consumer-0 is going to wait() consumer-1 is going to wait() consumer-0 get Notified
doProduce()执行notifyAll()的结果:
consumer-1 is going to wait()
consumer-0 is going to wait()
consumer-0 get Notified
consumer-1 is going to wait()
可以看到notifyAll()将会唤醒所有线程,导致consumer-1再次调用wait()方法