博客
关于我
Java多线程wait()和notify()系列方法使用教程(内涵故事)
阅读量:673 次
发布时间:2019-03-15

本文共 2859 字,大约阅读时间需要 9 分钟。

Java wait()和notify()方法实用解析

在Java中,wait()notify()方法是线程编程中的强大工具,用于实现线程间的等待与唤醒机制。它们被ictionary对象提供,是线程安全编程的基础之一。本文将通过两个线程的互动案例,详细解析这两个方法的工作原理及其使用规范。

一、方法概述

  • wait()方法:使当前线程等待。这意味着线程不会再竞争任何与当前共享对象相关的锁定。这一机制可以节省CPU资源,让线程暂停执行,等待某一特定条件的满足。
  • wait(long timeout)方法:带有超时参数的等待方法。若在指定时间内没有被notify()唤醒,超时会被自动抛出。传递负值时,会抛出IllegalStateException。默认情况下,参数为0,表示无限等待。
  • notify()方法:唤醒当前线程中等待共享对象锁定的线程之一。notify()通知的线程会立即返回,重新参与线程调度,但不会立即获得锁。
  • notifyAll()方法:唤醒所有等候共享对象锁定的线程。与queue方法类似,但作用范围更大。

使用这些方法需要遵循一定规则:

  • 区域同步:所有涉及共享对象的操作必须在同步块内,这确保了线程安全。
  • 单例对象:这些方法仅针对单个共享对象生效。如果需要同时等待多个共享对象,需重复调用wait()
  • 中断处理:若在等待期间,线程被中断,会抛出InterruptedException异常,需确保该异常被正确处理。
  • 二、典型案例解析

    为了直观理解wait()notify()的工作机制,我们设计了一个简单的示例场景:

    需求:让一个线程等待,而另一个线程在等待期间进行某种操作,并在完成后唤醒等待线程。

    步骤

  • 创建共享对象:确保多个线程能进行互动。
  • 启动线程:分别启动Thread0Thread1,分别执行不同的操作。
  • Thread0执行wait():当前线程获得锁,并进入等待状态。
  • Thread1获得锁,执行notify():在自己的操作完成后,唤醒等待的Thread0
  • Thread0恢复执行:重获锁定,继续后续操作。
  • 示例代码

    public class ThreadWaitAnd Notify {    private static Object object = new Object(); // 共享对象    static class Thread0 extends Thread {        @Override        public void run() {            synchronized (object) {                System.out.println("Thread-0:获得锁,执行wait()...");                 object.wait(); // 线程进入等待状态                System.out.println("Thread-0:从wait()恢复执行");            }        }    }    static class Thread1 extends Thread {        @Override        public void run() {            synchronized (object) {                System.out.println("Thread-1:获得锁,执行 notify()...");                 object.notify(); // 唤醒等待的线程                System.out.println("Thread-1:完成 notify()操作");            }        }    }    public static void main(String[] args) {        Thread0 thread0 = new Thread0();        Thread1 thread1 = new Thread1();        try {            thread0.start();            Thread.sleep(500); // 给Thread1时间先启动            thread1.start();        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

    运行输出

    Thread-0:获得锁,执行wait()...Thread-1:获得锁,执行 notify()...Thread-1:完成 notify()操作Thread-0:从wait()恢复执行

    这段输出明确展示了线程的等待与唤醒过程:

  • Thread-0获取共享对象锁,调用wait()后立即退出同步块,进入等待状态。
  • Thread-1启动,成功获取锁,调用notify(),通知Thread-0解除等待。
  • Thread-1离开同步块,(thread-0)随后恢复执行。
  • 三、线程的等待唤醒机制

    从示例中可以看到,wait()notify()的核心机制包括:

  • 线程交替:在获取锁后,Thread-0暂停执行,等待消息;Thread-1获得锁,修改状态,然后唤醒Thread-0
  • 资源释放:在执行完相关操作后,Thread-1归还锁;等待的Thread-0随后重新获取锁,继续执行。
  • 效率与资源:这种机制允许多个线程轮转使用唯一资源,最大化资源利用率。
  • 注意事项

  • 同步机制:所有与共享对象相关的操作都必须在同步块内修饰。否则,可能导致竞态条件或其他线程安全问题。
  • 资源分配:如果有多个共享对象,需要分别调用wait()方法,确保每个对象都能被正确管理。
  • 中断处理:在等待期间,若线程被中断,必须在catch块中妥善处理InterruptedException异常,避免死锁或逻辑错误。
  • 四、与生活场景对应的故事

    前文提到的“捡肥皂”故事,相当于一个简单的资源共享场景:

    • 王哥和李哥:一个拿到肥皂后,不断使用直到完成任务,随后归还资源,另一个线程可以接着使用。这种方式确保了资源的高效利用。
    • 小王和小李:双方“抢夺”肥皂,虽然并不真正等待,但资源分配显然不够优雅,容易引发冲突。

    网页内容提到的“老王和老李”,则是最理想的情况:

    • 他们不仅能够高效共享资源,还能灵活分配使用。

    五、总结

    通过示例和生活化的类比,我们可以清晰地看到wait()notify()方法的作用及其重要性。要正确使用这些方法,需遵守线程安全的原则,并结合实际场景进行合理设计。理解这些方法的使用场景,将有助于我们更好地设计和实现高效的多线程应用程序。

    欢迎转载和分享!

    你可能感兴趣的文章
    MYSQL中TINYINT的取值范围
    查看>>
    MySQL中UPDATE语句的神奇技巧,让你操作数据库如虎添翼!
    查看>>
    Mysql中varchar类型数字排序不对踩坑记录
    查看>>
    MySQL中一条SQL语句到底是如何执行的呢?
    查看>>
    MySQL中你必须知道的10件事,1.5万字!
    查看>>
    MySQL中使用IN()查询到底走不走索引?
    查看>>
    Mysql中使用存储过程插入decimal和时间数据递增的模拟数据
    查看>>
    MySql中关于geometry类型的数据_空的时候如何插入处理_需用null_空字符串插入会报错_Cannot get geometry object from dat---MySql工作笔记003
    查看>>
    mysql中出现Incorrect DECIMAL value: '0' for column '' at row -1错误解决方案
    查看>>
    mysql中出现Unit mysql.service could not be found 的解决方法
    查看>>
    mysql中出现update-alternatives: 错误: 候选项路径 /etc/mysql/mysql.cnf 不存在 dpkg: 处理软件包 mysql-server-8.0的解决方法(全)
    查看>>
    Mysql中各类锁的机制图文详细解析(全)
    查看>>
    MySQL中地理位置数据扩展geometry的使用心得
    查看>>
    Mysql中存储引擎简介、修改、查询、选择
    查看>>
    Mysql中存储过程、存储函数、自定义函数、变量、流程控制语句、光标/游标、定义条件和处理程序的使用示例
    查看>>
    mysql中实现rownum,对结果进行排序
    查看>>
    mysql中对于数据库的基本操作
    查看>>
    Mysql中常用函数的使用示例
    查看>>
    MySql中怎样使用case-when实现判断查询结果返回
    查看>>
    Mysql中怎样使用update更新某列的数据减去指定值
    查看>>