wait和notify等待和释放——控制多个线程执行顺序

目录

wait和notify

wait等待——进入阻塞

notify唤醒线程


wait和notify

是多线程中一个比较重要的机制,协调多个线程的执行顺序的

本身多个线程的执行顺序是随机的(抢占式 系统随机调度)

我们希望通过一定手段控制线程执行顺序

wait等待,让指定线程进入阻塞状态

notify通知,唤醒对应的阻塞状态的线程

wait和notify需要借助同一个对象,并且都需要搭配synchronized使用

wait等待——进入阻塞

 Object object=new Object();
 System.out.println("wait之前");
 object.wait(3000);
 System.out.println("wait之后");

报错IllegalMonitorStateException非法的监视器状态异常

此处的监视器指synchronized(也叫监视器锁)

原因:

wait在执行的时候,要做三件事

①释放当前锁

②让线程进入阻塞

③当线程被唤醒的时候,重新获取到锁

(①也就意味着,我们需要提前加上锁)

正确使用方式:


        Object object1 = new Object();

        synchronized (object) {
            System.out.println("wait 之前");
            // 把 wait 要放到 synchronized 里面来调用. 保证确实是拿到锁了的.
            object1.wait();
            System.out.println("wait 之后");
        }

注意:

wait只能由持有相应对象监视器锁的线程调用 也就是说加锁的对象(object1)要与调用wait的对象式=是同一个

wait会持续阻塞等待下去,直到其他线程调用notify唤醒

wait还有一个有参版本,指定了最多等待时间

使用wait notify也可以避免”线程饿死“

使用wait后(wait内部本身会释放锁,并且进入阻塞),1号就不会参与后续的锁竞争了,把锁释放出来让别人获取

wait是等的状态,是阻塞的,啥都不做,不会占据cpu


notify唤醒线程

notify一次唤醒一个线程

notiftAll一次唤醒全部线程(多个线程调用wait)(

public static void main(String args[]) throws InterruptedException {
        Object object=new Object();
        Thread t1=new Thread(()->{
           synchronized (object){
               System.out.println("t1获取锁");
               try {
                   object.wait();
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("t1再次获取锁");
           }
        });

        Thread t2=new Thread(()->{
           synchronized (object){
               System.out.println("t2获取锁");
               object.notify();
               System.out.println("t2仍在运行");
           }
        });
        t1.start();
        t2.start();
    }

①调用 wait 方法后,释放持有的对象锁,线程状态有 Running 变为 Waiting,并将当前线程放置到对象的 等待队列;
②调用notify 或者 notifyAll 方法后,等待线程依旧不会从 wait 返回,需要调用 noitfy 的线程释放锁之后,等待线程才有机会从 wait 返回;
③notify 方法:将等待队列的一个等待线程从等待队列种移到同步队列中 ,
④notifyAll 方法:将等待队列种所有的线程全部移到同步队列,被移动的线程状态由 Waiting 变为 Blocked。
————————————————             
原文链接:https://blog.csdn.net/qq_40662405/article/details/120484313

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值