线程通讯的三种方法(线程的等待和唤醒功能)

一、线程通讯三个方法(对象级别、都是Object类 的内置方法):

二、wait方法的使用

演示代码:

三、notify使用

代码演示:

运行结果:

四、 notifyAll使用

代码演示:

运行结果:

五、线程通讯注意事项


一、线程通讯三个方法(对象级别、都是Object类 的内置方法):

1.wait()/wait(long timeout):线程进入休眠

2.notify:随机唤醒进入休眠状态的线程

3.notifyAll:唤醒所有处于休眠状态的线程

注意事项:以上三种方法都必须配合synchronized一起使用,否则会报错

二、wait方法的使用

首先我们来了解一下wait的执行流程:

  • 使当前执行代码的线程进行等待(把线程放在等待队列中)
  • 释放当前的锁
  • 满足一定条件时被唤醒,重新尝试这个锁

演示代码:

package thread.threaddemo;

/**
 * @Author: wenjingyuan
 * @Date: 2023/01/14/23:35
 * @Description:wait()方法
 */
public class WaitDemo {
    public static void main(String[] args) {
        Object lock=new Object();
        Thread t1=new Thread(()->{
            //
            System.out.println("线程1开始执行");
            try {
                synchronized (lock){
                    System.out.println("线程1调用wait方法");
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1结束执行");
        },"线程1");
        t1.start();
    }
}

三、notify使用

代码演示:

package thread.threaddemo;

/**
 * @Author: wenjingyuan
 * @Date: 2023/01/14/23:35
 * @Description:notify()方法
 */
public class WaitDemo2 {
    public static void main(String[] args) {
        Object lock=new Object();
        Object lock2=new Object();
        Thread t1=new Thread(()->{
            //
            System.out.println("线程1开始执行");
            try {
                synchronized (lock){
                    System.out.println("线程1调用wait方法");
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1结束执行");
        },"线程1");
        t1.start();

        Thread t2=new Thread(()->{
            //
            System.out.println("线程2开始执行");
            try {
                synchronized (lock){
                    System.out.println("线程2调用wait方法");
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程2结束执行");
        },"线程2");
        t2.start();

        Thread t3=new Thread(()->{
            //
            System.out.println("线程3开始执行");
            try {
                synchronized (lock2){
                    System.out.println("线程3调用wait方法");
                    lock2.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程3结束执行");
        },"线程3");
        t3.start();

        //线程4执行唤醒线程
        Thread t4=new Thread(()->{
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程4开始执行");
            synchronized (lock){
                lock.notify();
                System.out.println("线程4执行唤醒操作");
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程4 执行结束");
            }
        },"线程4");
        t4.start();
    }
}

运行结果:

注意事项:notify调用之后并不是立马唤醒线程开始执行,而是要等待notify中synchronized执行结束(锁释放)才能真正的被唤醒起来开始执行 

四、 notifyAll使用

代码演示:

package thread.threaddemo;

/**
 * @Author: wenjingyuan
 * @Date: 2023/01/14/23:35
 * @Description:notify()方法
 */
public class WaitDemo3 {
    public static void main(String[] args) {
        Object lock=new Object();
        Object lock2=new Object();
        Thread t1=new Thread(()->{
            //
            System.out.println("线程1开始执行");
            try {
                synchronized (lock){
                    System.out.println("线程1调用wait方法");
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1结束执行");
        },"线程1");
        t1.start();

        Thread t2=new Thread(()->{
            //
            System.out.println("线程2开始执行");
            try {
                synchronized (lock){
                    System.out.println("线程2调用wait方法");
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程2结束执行");
        },"线程2");
        t2.start();

        Thread t3=new Thread(()->{
            //
            System.out.println("线程3开始执行");
            try {
                synchronized (lock){
                    System.out.println("线程3调用wait方法");
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程3结束执行");
        },"线程3");
        t3.start();

        //线程4执行唤醒线程
        Thread t4=new Thread(()->{
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程4开始执行");
            synchronized (lock){
                lock.notifyAll();
                System.out.println("线程4执行唤醒操作");
//                try {
//                    Thread.sleep(2000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println("线程4 执行结束");
            }
        },"线程4");
        t4.start();
    }
}

运行结果:

五、线程通讯注意事项

1.wait/notify/notifyAll必须要配合synchronized一起使用

2. wait/notify/notifyAll进行synchronized加锁的时候,一定要使用同一个对象进行加锁

3.当调用了Notify/notifyAll之后,程序不会立即恢复执行,而是尝试获取锁,只有得到锁之后才能继续执行 

4.notifyAll并不是唤醒所有的wait等待的线程的,而是唤醒当前对象处于wait等待的所有线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值