wait,notify,notifyAll从使用到原理图详解(含高频面试题和使用wait_notify实现生产者消费者问题)

1 wait,notify,notifyAll方法详解

1.1 作用、用法

我们可以通过上面方法控制一些线程去休息或唤醒

当一个线程使用wait方法时,这个线程被阻塞(阻塞阶段)并且释放锁

由阻塞状态变为唤醒阶段有几种情况?

  1. 另一个线程调用这个对象的notify()方法且刚好被唤醒的是本线程
  2. 另一个线程调用这个对象的notifyAll()方法
  3. 过了wait( long timeout )规定的时间,如果传入0就是永久等待
  4. 线程自身调用了interrupt()

遇到中断会由阻塞状态变为唤醒状态

public static void main (String[] args) throws InterruptedException {
   
    Thread t1 = new Thread(new Runnable() {
   
        @Override
        public void run () {
   
            try {
   
                System.out.println("t1 begin sleep 2000 seconds");
                Thread.sleep(2000000);
                System.out.println("t1 awaking");
            } catch (InterruptedException e) {
   
                System.out.println("t1 is interrupted while sleeping");
                return;
            }

            System.out.println("t1 continue working");
        }
    });
    t1.start();
    Thread.sleep(1000);
    //打断子线程的休眠,让子线程从sleep函数返回
    t1.interrupt();
    //等待子线程执行完毕
    t1.join();
    System.out.println("main thread is over");
}

输出

在这里插入图片描述

1.2 代码演示

wait演示

public class Wait {
   
    static Object object = new Object();
    static class Thread1 extends Thread{
   
        @Override
        public void run () {
   
            synchronized (object){
   
                System.out.println("线程"+Thread.currentThread().getName()+"开始执行");
                try {
   
                    object.wait();//释放了锁,并且将线程t1阻塞
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
                System.out.println("线程"+Thread.currentThread().getName()+"释放了锁");
            }
        }
    }
    static class Thread2 extends Thread{
   
        @Override
        public void run () {
   
            synchronized (object){
   
                object.notify();
                System.out.println("线程"+Thread.currentThread().getName()+"调用了notify()");
            }
        }
    }

    public static void main (String[] args) throws InterruptedException {
   
        Thread1 t1 = new Thread1();
        Thread2 t2 = new Thread2();
        t1.start();
        Thread.sleep(2000);
        t2.start();
    }
}

输出

线程Thread-0开始执行
线程Thread-1调用了notify()
线程Thread-0释放了锁

描述一下代码执行的整个过程:

  • 线程t1得到了锁object,打印出"线程Thread-0开始执行"
  • 线程执行到了object.wait()。锁object被释放,线程t1被阻塞
  • 线程t2得到了锁object,执行语句object.notify(),此时线程t1被
  • 唤醒,但是该线程不能获得锁object。必须要等t2释放了锁之后才能运行
  • t1重新获取到锁之后会返回之前的位置,继续执行代码

notifyAll演示

/**
 * 线程1和2首先被阻塞,线程3唤醒它们
 */
public class WaitNotifyAll implements Runnable
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值