貌似不能唤醒指定的线程,如果想唤起指定的线程,需要用到Lock锁的Condition条件
几个重要的概念:
《java编程思想》第四版一书中有描述到:“线程操作的wait()、notify()、notifyAll()方法只能在同步控制方法或同步控制块内调用。如果在非同步控制方法或控制块里调用,程序能通过编译,但运行的时候,将得到 IllegalMonitorStateException 异常,并伴随着一些含糊信息,比如 ‘当前线程不是拥有者’。其实异常的含义是 调用wait()、notify()、notifyAll()的任务在调用这些方法前必须 ‘拥有’(获取)对象的锁。”
即必须在方法上加上synchronized关键字
wait:当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。后面的代码不会执行。当该线程被唤醒之后会接着后面的代码执行
wait(1000) 还可以设置时间
notify/notifyAll:
notify随机唤醒的是其所在锁所阻塞的线程 notifyAll唤醒的是全部其所在锁所阻塞的线程
package com.juc.等待唤醒;/*** 线程之间的通信问题:生产者和消费者问题! 等待唤醒,通知唤醒* 线程交替执行 A B 操作同一个变量 num = 0* A num+1* B num-1*/public class A {public static void main(String[] args) {Data data = new Data();new Thread(()->{for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}},"A").start();new Thread(()->{for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}},"B").start();new Thread(()->{for (int i = 0; i < 10; i++) {try {data.increment();} catch (InterruptedException e) {e.printStackTrace();}}},"C").start();new Thread(()->{for (int i = 0; i < 10; i++) {try {data.decrement();} catch (InterruptedException e) {e.printStackTrace();}}},"D").start();}}// 判断等待,业务,通知class Data{ // 数字 资源类private int number = 0;//+1public synchronized void increment() throws InterruptedException {while (number!=0){ //0// 等待this.wait();}number++;System.out.println(Thread.currentThread().getName()+"=>"+number);// 通知其他线程,我+1完毕了this.notifyAll();}//-1public synchronized void decrement() throws InterruptedException {while (number==0){ // 1// 等待this.wait();}number--;System.out.println(Thread.currentThread().getName()+"=>"+number);// 通知其他线程,我-1完毕了this.notifyAll();}}
A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0A=>1B=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0C=>1D=>0
