文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java怎么使用wait或notify实现线程间通信

2023-07-04 19:27

关注

这篇文章主要介绍“Java怎么使用wait或notify实现线程间通信”,在日常操作中,相信很多人在Java怎么使用wait或notify实现线程间通信问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java怎么使用wait或notify实现线程间通信”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

1. 当 interrupt() 方法遇到 wait() 方法

当线程调用锁对象的wait() 方法使线程呈等待状态时,调用线程对象的 interrupt() 方法会出现 InterruptedException 异常。

public class ThreadC7 {    @Test    public void test1() {        try {            Object obj = new Object();            ThreadC7A threadC7A = new ThreadC7A(obj);            threadC7A.start();            Thread.sleep(2000);            threadC7A.interrupt();        } catch (Exception e) {            e.printStackTrace();        }    }}class ServiceC7 {    public void testMethod(Object obj) {        try {            synchronized (obj) {                System.out.println("begin wait");                obj.wait();                System.out.println("begin end");            }        } catch (Exception e) {            e.printStackTrace();            System.out.println("出现异常了,wait状态的线程被interrupt了!");        }    }}class ThreadC7A extends Thread {    private Object obj;    public ThreadC7A(Object obj) {        this.obj = obj;    }    @Override    public void run() {        ServiceC7 serviceC7 = new ServiceC7();        serviceC7.testMethod(obj);    }}

执行结果:

Java怎么使用wait或notify实现线程间通信

2. notify() 只通知一个线程

调用方法notify()一次只随机通知一个线程进行唤醒。

public class ThreadC8 {    @Test    public void test() {        Object obj = new Object();        ThreadC8A threadC8A = new ThreadC8A(obj);        threadC8A.setName("threadC8A");        threadC8A.start();        ThreadC8B threadC8B = new ThreadC8B(obj);        threadC8B.setName("threadC8B");        threadC8B.start();        ThreadC8C threadC8C = new ThreadC8C(obj);        threadC8C.setName("threadC8C");        threadC8C.start();        try {            Thread.sleep(1000);        } catch (Exception e) {            e.printStackTrace();        }        synchronized (obj) {            obj.notify();        }        while (Thread.activeCount() > 1) {        }    }}class ServiceC8 {    public void service(Object obj) {        try {            synchronized (obj) {                String threadName = Thread.currentThread().getName();                System.out.println("begin wait,Thread Name:[" + threadName + "]");                obj.wait();                System.out.println("end wait,Thread Name:[" + threadName + "]");            }        } catch (Exception e) {            e.printStackTrace();        }    }}class ThreadC8A extends Thread {    private Object obj;    public ThreadC8A(Object obj) {        this.obj = obj;    }    @Override    public void run() {        ServiceC8 serviceC8 = new ServiceC8();        serviceC8.service(obj);    }}class ThreadC8B extends Thread {    private Object obj;    public ThreadC8B(Object obj) {        this.obj = obj;    }    @Override    public void run() {        ServiceC8 serviceC8 = new ServiceC8();        serviceC8.service(obj);    }}class ThreadC8C extends Thread {    private Object obj;    public ThreadC8C(Object obj) {        this.obj = obj;    }    @Override    public void run() {        ServiceC8 serviceC8 = new ServiceC8();        serviceC8.service(obj);    }}

执行结果:

Java怎么使用wait或notify实现线程间通信

程序运行的效果如图所示,可以看出方法notify()仅随机唤醒一个线程。

当多次调用notify()方法时,会随机将等待wait状态的线程进行唤醒。更改代码如下:

Java怎么使用wait或notify实现线程间通信

再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。

Java怎么使用wait或notify实现线程间通信

多次调用notify()方法可唤醒全部WAITING中的线程。

3. notifyAll() 唤醒所有线程

前面的示例中通过多次调用 notify() 方法来实现唤醒3个线程,但并不能保证系统中仅有3个线程,也就是若notify()方法的调用次数小于线程对象的数量,会出现有部分线程对象无法被唤醒的情况。为了唤醒全部线程,可以使用notifyAll()方法。

更改代码如下:

Java怎么使用wait或notify实现线程间通信

再次运行,程序运行效果如图所示,可以看出所有的线程全部被唤醒。

Java怎么使用wait或notify实现线程间通信

4. 方法 wait(long)的使用

带一个参数的wait(long) 方法的功能是等待某一时间内是否有现成对锁进行唤醒,如果超过这个时间则自动唤醒。

public class ThreadC9 {    @Test    public void test() {        Object obj = new Object();        ThreadC9A threadC9A = new ThreadC9A(obj);        threadC9A.start();        while (Thread.activeCount() > 1) {        }    }}class ThreadC9A extends Thread {    private Object obj;    public ThreadC9A(Object obj) {        this.obj = obj;    }    @Override    public void run() {        try {            synchronized (obj) {                long startTime = System.currentTimeMillis();                System.out.println("begin wait,time:[" + startTime + "]");                obj.wait(5000);                long endTime = System.currentTimeMillis();                System.out.println("end wait,time:[" + endTime + "] takes " + (endTime - startTime) + " ms");            }        } catch (Exception e) {            e.printStackTrace();        }    }}

执行结果:

Java怎么使用wait或notify实现线程间通信

通过执行结果可以看出,在经过5000ms后,线程被唤醒。

到此,关于“Java怎么使用wait或notify实现线程间通信”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯