详细分析java线程wait和notify

 更新时间:2015年07月29日 10:33:58   作者:ketqi  
本篇文章是对java多线程wait()和notify()进行了详细的分析介绍,需要了解的朋友参考下

wait()和notify()是直接隶属于Object类,也就是说,所有对象都拥有这一对方法。初看起来这十分 不可思议,但是实际上却是很自然的,因为这一对方法阻塞时要释放占用的锁,而锁是任何对象都具有的,调用任意对象的 wait() 方法导致线程阻塞,并且该对象上的锁被释放。而调用任意对象的notify()方法则导致因调用该对象的wait() 方法而阻塞的线程中随机选择的一个解除阻塞(但要等到获得锁后才真正可执行)。

其次,wait()和notify()可在任何位置调用,但是这一对方法却必须在 synchronized 方法或块中调用,理由也很简单,只有在 synchronized 方法或块中当前线程才占有锁,才有锁可以释放。同样的道理,调用这一对方法的对象上的锁必须为当前线程所拥有,这样才有锁可以 释放。因此,方法调用必须放置在这样的 synchronized 方法或块中,该方法或块的加锁对象就是调用这些方法的对象。若不满足这一条 件,则程序虽然仍能编译,但在运行时会出现IllegalMonitorStateException 异常。

 wait() 和 notify() 方法的上述特性决定了它们经常和synchronized 方法或块一起使用,将它们和操作系统的进程间通信机制作 一个比较就会发现它们的相似性:synchronized方法或块提供了类似于操作系统原语的功能,它们的执行不会受到多线程机制的干扰,而这一对方法则 相当于 block 和wakeup 原语(这一对方法均声明为 synchronized)。它们的结合使得我们可以实现操作系统上一系列精妙的进程间 通信的算法(如信号量算法),并用于解决各种复杂的线程间通信问题。
 

关于 wait() 和 notify() 方法最后再说明两点:
    第一:调用 notify() 方法导致解除阻塞的线程是从因调用该对象的 wait() 方法而阻塞的线程中随机选取的,我们无法预料哪一个线程将会被选择,所以编程时要特别小心,避免因这种不确定性而产生问题。
    第二:除了 notify(),还有一个方法 notifyAll() 也可起到类似作用,唯一的区别在于,调用 notifyAll() 方法将把因调 用该对象的 wait() 方法而阻塞的所有线程一次性全部解除阻塞。当然,只有获得锁的那一个线程才能进入可执行状态。

相关wait和notify使用demo:

/**
 * <pre>
 * 子线程循环10次,接着主线程循环100次,接着有回到子线程循环10次,
 * 接着再回到主线程循环100次,如此执行50次
 * </pre>
 * @author ketqi
 */
 public class WaitNotifyDemo {
   public static void main(String[] args) {
 
     final Business business = new Business();
     new Thread(new Runnable() {
       @Override
       public void run() {
         for (int i = 1; i <= 50; i++) {
           business.sub(i);
         }
 
       }
     }).start();
 
     for (int i = 1; i <= 50; i++) {
       business.main(i);
     }
   }
 }
 
 class Business {
   private boolean isMainThread = true;
 
   public synchronized void sub(int i) {
     while (!isMainThread) {
       try {
         this.wait();
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
     for (int j = 1; j <= 10; j++) {
       System.out.println("sub thread sequence of " + j + ",loop of " + i);
    }
     isMainThread = false;
     this.notify();
   }
 
  public synchronized void main(int i) {
     while (isMainThread) {
       try {
        this.wait();
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
     }
     for (int j = 1; j <= 100; j++) {
       System.out.println("main thread sequence of " + j + ",loop of " + i);
     }
     isMainThread = true;
     this.notify();
   }
 }

以上就是本文的全部内容,希望大家可以喜欢。

相关文章

  • Java数据结构及算法实例:汉诺塔问题 Hanoi

    Java数据结构及算法实例:汉诺塔问题 Hanoi

    这篇文章主要介绍了Java数据结构及算法实例:汉诺塔问题 Hanoi,本文直接给出实现代码,代码中包含大量注释,需要的朋友可以参考下
    2015-06-06
  • java阻塞队列实现原理及实例解析

    java阻塞队列实现原理及实例解析

    这篇文章主要介绍了java阻塞队列实现原理及实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java编程多线程之共享数据代码详解

    Java编程多线程之共享数据代码详解

    这篇文章主要介绍了Java编程多线程之共享数据代码详解,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • java 重试框架 sisyphus 入门介绍

    java 重试框架 sisyphus 入门介绍

    sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活,本文给大家介绍java 重试框架 sisyphus 入门相关知识,感兴趣的朋友一起看看吧
    2021-10-10
  • Java Swing组件JFileChooser用法实例分析

    Java Swing组件JFileChooser用法实例分析

    这篇文章主要介绍了Java Swing组件JFileChooser用法,结合实例形式分析了java Swing组件JFileChooser文件选择器的功能、使用方法及相关注意事项,需要的朋友可以参考下
    2017-11-11
  • Java中Scanner类使用保姆级教程

    Java中Scanner类使用保姆级教程

    JavaSE在java.util类库中提供了一个专门用于输入操作的类Scanner类,可以使用该类创建一个对象,然后利用该对象的相关方法从键盘上读取数据,下面这篇文章主要给大家介绍了关于Java中Scanner类使用的相关资料,需要的朋友可以参考下
    2023-04-04
  • IDEA中Web项目控制台乱码的问题及解决方法

    IDEA中Web项目控制台乱码的问题及解决方法

    这篇文章主要介绍了IDEA中Web项目控制台乱码的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • springboot泛型封装开发方式

    springboot泛型封装开发方式

    这篇文章主要介绍了springboot泛型封装开发方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • Java中Spring Boot支付宝扫码支付及支付回调的实现代码

    Java中Spring Boot支付宝扫码支付及支付回调的实现代码

    这篇文章主要介绍了Java中Spring Boot支付宝扫码支付及支付回调的实现代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • SpringBoot实现异步事件驱动的方法

    SpringBoot实现异步事件驱动的方法

    本文主要介绍了SpringBoot实现异步事件驱动的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-06-06

最新评论