等待唤醒机制 -多个线程在操作同一份数据时,避免对同一变量进行争夺
目的:有效利用资源
重点:对资源占用的判断
注:notify只会唤醒同一锁对象
- wait与notify必须在同步代码块或者同步方法中使用
 - 通过锁对象调用
 
public class ThreadWaitNotifyAll {
    public static void main(String[] args) {
        Object obj = new Object();
        //匿名内部类创建一个线程
        new Thread("消费者线程"){
            @Override
            public void run() {
                //等待唤醒只能有一个线程进行,利用同步机制
                synchronized (obj) {
                    System.out.println("消费者:老板我要买东西,给你2s");
                    try {
                        obj.wait(2000);  //无限等待,直到被唤醒
                        System.out.println("消费者:收到了,谢谢老板,我带走了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        new Thread("消费者1线程"){
            @Override
            public void run() {
                //等待唤醒只能有一个线程进行,利用同步机制
                synchronized (obj) {
                    System.out.println("消费者01:老板我要买东西,给你2s");
                    try {
                        obj.wait(2000);  //无限等待,直到被唤醒
                        System.out.println("消费者01:收到了,谢谢老板,我带走了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //在创建一个线程
        new Thread("老板线程"){
            @Override
            public void run() {
                //上面线程等待5s
                System.out.println("老板:谢谢你们的5s钟");
                synchronized (obj) {
                    System.out.println("老板:我做好了,来拿吧");
                    //会唤醒调度队列队头的进程 obj.notify();
                    //由于是在同步块内,此刻没锁,唤醒后会再获取锁,获取成功RUNNABLE
                    // 若没获取到,会重新进入调度队列 entry set,WAITING转为BLOCKED状态
                    //全部唤醒
                    obj.notifyAll();
                }
            }
        }.start();
    }
}
注:顾客和老板线程必须用同步代码块锁起来,保证有一个在执行
- 同步锁对象必须保证唯一
 - 只有锁对象能调用wait()/notify()方法
 
在Object类中
void wait()
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
void notify()
唤醒在此对象监视器上等待的单个线程。
void notifyAll()
唤醒在此对象监视器上等待的所有线程,会继续执行wait之后的方法
public class ThreadState {
    public static void main(String[] args) {
        Object obj = new Object();
        //匿名内部类创建一个线程
        new Thread("消费者线程"){
            @Override
            public void run() {
                //等待唤醒只能有一个线程进行,利用同步机制
                synchronized (obj) {
                    System.out.println("消费者:老板我要买东西");
                    try {
                        obj.wait();  //无限等待,直到被唤醒
                        System.out.println("消费者:收到了,谢谢老板,我带走了");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //在创建一个线程
        new Thread("老板线程"){
            @Override
            public void run() {
                //花5秒准备东西
                try {
                    System.out.println("老板:好的,等我五秒钟准备一下");
                    Thread.sleep(0000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //唤醒一个线程
                synchronized (obj) {
                    System.out.println("老板:我做好了,来拿吧");
                    obj.notify();  //唤醒上面的线程,执行wait之后的代码,但是该线程还没结束
                    //下面代码仍然在抢占cpu的执行权,因为唤醒后,当前线程还未解锁
                    System.out.println("老板:哈哈,骗你的继续等吧");
                }
                //休息会儿让上面的线程先走
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //上面线程结束
                System.out.println("老板:不客气");
            }
        }.start();
    }
}
原文:https://www.cnblogs.com/huxiaobai/p/11541254.html