快速了解多线程的wait与notify

由于线程与线程之间是抢占式执行是, 因此线程之间的执行顺序是无法预测的, 但有时候又希望可以合理的协调线程之间的先后执行顺序, 所以想完成这个协调工作, 主要涉及到三个方法.

wait()方法

       wait的作用

       使当前执行代码的线程进入等待;

       释放当前锁;

       当满足一定条件时会被唤醒,重新获取释放的锁;

wait结束等待的条件

       其他线程调用该对象的notify方法;

       Wait等待时间超时(wait方法提供了一个带有时间参数的方法,可以指定等待时间);

       其他线程调用该等待线程的interrupted方法,导致wait抛出InterruptedException 异常.

代码演示

       public static void main(String[] args) throws InterruptedException {

              object object = new Object();

              synchronized (object) {

                     System.out.println("等待中");

                     object.wait();

                     System.out.println("等待结束");

              }

       }

当代码执行到object.wait之后就会一直等待下去, 线程进入等待, 如果想唤醒线程就需要使用notify()方法,将线程唤醒.

notify()方法

notify方法由于唤醒等待线程

使用方式

 1.方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁         的 其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。

  2.如果有多个线程等待,则有线程调度器随机挑选出一个呈 wait 状态的线程。(并没有 "先来后            到")

   3.在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行         完,也就是退出同步代码块之后才会释放对象锁。

代码示例:

       public class WaitTask implements  Runnable{
    private  Object locker;
    public  WaitTask(Object locker){
        this.locker = locker;
    }
    @Override
    public void run() {
        synchronized (locker){
            while (true){
                try {
                    System.out.println("wait 开始");
                    locker.wait();
                    System.out.println("wait 结束");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
class NotifyTask implements Runnable{
    private Object locker;
    public NotifyTask(Object locker){
        this.locker = locker;
    }
    @Override
    public void run() {
        synchronized (locker){
            System.out.println("notify 开始");
            locker.notify();
            System.out.println("notify 结束");
        }
    }

    public static void main(String[] args) {
        Object locker = new Object();
        Thread thread1 = new Thread(new NotifyTask(locker));
        Thread thread2 = new Thread(new WaitTask(locker));
        thread2.start();
        thread1.start();
    }
}

notifyAll()方法

notify方法只是唤醒某一个等待线程, 使用notifyAll方法可以一次唤醒所有的等待线程

范例:使用notifyAll()方法唤醒所有等待线程.

public class WaitTask implements  Runnable{
    private  Object locker;
    public  WaitTask(Object locker){
        this.locker = locker;
    }
    @Override
    public void run() {
        synchronized (locker){
                try {
                    System.out.println("WaitTask wait 开始");
                    locker.wait();
                    System.out.println("WaitTask wait 结束");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
        }
    }
}
class WaitTask1 implements  Runnable{
    private  Object locker;
    public  WaitTask1(Object locker){
        this.locker = locker;
    }
    @Override
    public void run() {
        synchronized (locker){
                try {
                    System.out.println("WaitTask1 wait 开始");
                    locker.wait();
                    System.out.println("WaitTask1 wait 结束");
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
}
class NotifyTask implements Runnable{
    private Object locker;
    public NotifyTask(Object locker){
        this.locker = locker;
    }
    @Override
    public void run() {
        synchronized (locker){
            System.out.println("notify 开始");
            locker.notifyAll();
            System.out.println("notify 结束");
        }
    }

    public static void main(String[] args) {
        Object locker = new Object();
        Thread thread1 = new Thread(new NotifyTask(locker));
        Thread thread2 = new Thread(new WaitTask(locker));
        Thread thread3 = new Thread(new WaitTask1(locker));

        thread2.start();
        thread3.start();
        thread1.start();

    }
}

注意: 虽然notifyAll()方法会唤醒所有等待线程,但线程之间还需要竞争锁,并不遵循先来后到.

本次学习讲解到此为止了, 如果感到对你有帮助的话的,给个免费的赞支持一下作者哦

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值