wait和notify

avatar 2020年08月20日16:55:03 7 2598 views
博主分享免费Java教学视频,B站账号:Java刘哥

线程状态图

开局先奉上这张线程状态图,个人觉得画的不错

几点结论

  • 使用 wait ,notify 和 notifyAll 时需要先对调用对象加锁。
  • 调用 wait 方法后,线程状态有 Running 变为 Waiting,并将当前线程放置到对象的 等待队列
  • notify 或者 notifyAll 方法调用后, 等待线程依旧不会从 wait 返回,需要调用 noitfy 的线程释放锁之后,等待线程才有机会从 wait 返回
  • notify 方法将等待队列的一个等待线程从等待队列种移到同步队列中,而 notifyAll 方法则是将等待队列种所有的线程全部移到同步队列,被移动的线程状态由 Waiting 变为 Blocked。
  • 从 wait 方法返回的前提是获得了调用对象的锁。

 

wait 和 notify 例子

import java.util.concurrent.TimeUnit;

public class WaitNotify {

  final static Object lock = new Object();

  public static void main(String[] args) {

    new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("线程 A 等待拿锁");
        synchronized (lock) {
          try {
            System.out.println("线程 A 拿到锁了");
            TimeUnit.SECONDS.sleep(1);
            System.out.println("线程 A 开始等待并放弃锁");
            lock.wait();
            System.out.println("线程 A 被通知可以继续执行 则 继续运行至结束");
          } catch (InterruptedException e) {
          }
        }
      }
    }, "线程 A").start();

    new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("线程 B 等待锁");
        synchronized (lock) {
          System.out.println("线程 B 拿到锁了");
          try {
            TimeUnit.SECONDS.sleep(5);
          } catch (InterruptedException e) {
          }
          lock.notify();
          System.out.println("线程 B 随机通知 Lock 对象的某个线程");
        }
      }
    }, "线程 B").start();
  }


}

运行结果如下:

线程 A 等待拿锁

线程 A 拿到锁了

线程 B 等待锁

线程 A 开始等待并放弃锁

线程 B 拿到锁了

线程 B 随机通知 Lock 对象的某个线程

线程 A 被通知可以继续执行 则 继续运行至结束

 

关于wait()和sleep()

这两个方法都可以让线程等待,但是wait()方法可以被唤醒。还有一个重要的区别是wait()会释放目标对象锁,而sleep()不会释放任何资源

 

  • wait和sleep方法都可以使线程进人阻塞状态。
  • wait和sleep方法均是可中断方法,被中断后都会收到中断异常。
  • wait是Object的方法,而sleep是Thread特有的方法。
  • wait方法的执行必须在同步方法中进行,而sleep则不需要。
  • 线程在同步方法中执行sleep方法时,并不会释放monitor的锁,而wait方法则会释放monitor的锁。
  • sleep方法短暂休眠之后会主动退出阻塞,而wait方法(没有指定wait时间)则需要被其他线程中断后才能退出阻塞
  • 微信
  • 交流学习,有偿服务
  • weinxin
  • 博客/Java交流群
  • 资源分享,问题解决,技术交流。群号:590480292
  • weinxin
avatar

发表评论

avatar 登录者:匿名
匿名评论,评论回复后会有邮件通知

  

已通过评论:1   待审核评论数:0
  1. avatar mayun

    测试评论