温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中等待唤醒机制的原理是什么

发布时间:2021-06-16 14:10:37 来源:亿速云 阅读:147 作者:Leah 栏目:编程语言

本篇文章为大家展示了Java中等待唤醒机制的原理是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

线程的状态

首先了解一下什么是线程的状态,线程状态就是当线程被创建(new),并且启动(start)后,它不是一启动就进入了执行状态(run),也不是一直都处于执行状态。

这里说一下Java 的Thread类里面有一个State方法,这个方法里面涵盖了6种线程的状态,如下:

public enum State {
  // 尚未启动的线程的线程状态。
  NEW,

  // 可运行线程的线程状态。
  RUNNABLE,

  // 线程的线程状态被阻塞,等待监视器锁定。
  BLOCKED,

  // 等待线程的线程状态。
  WAITING,

  // 具有指定等待时间的等待线程的线程状态。
  TIMED_WAITING,

  // 终止线程的线程状态。
  TERMINATED;
}

导致这六种线程状态发生的条件

New -- 新建

线程刚被创建,不过还没有被启动(还没有调用start方法)

Runnable -- 可运行

处于可运行状态的线程正在Java虚拟机中执行,但是它可能正在等待来自操作系统(例如处理器)的其他资源。

Blocked -- 锁阻塞
当一个线程想获取一个对象锁,不过该对象锁被其它的线程持有时,该线程就会进入锁阻塞状态;当该线程持有锁的时候,该线程将会变成可运行的状态。

Waiting -- 无限等待

当一个线程在等待另一个线程执行一个(唤醒)动作时,该线程就会进入无限等待状态。进入这个状态后是不能自动唤醒的,要等待另一个线程调用notify()方法,或notifyall()方法才能够被唤醒。

Timed_Waiting -- 计时等待

类似于无限等待状态,有几个方法有超时参数,如:Thread.sleep、Object.wait方法。调用这些方法,进入计时等待状态。计时等待状态将会一直保持到超时期满或者接收到唤醒通知。

terminated -- 被终止

1、因为run方法的正常退出而死亡。

2、因为没有捕获的异常,终止了run方法而死亡。

等待唤醒案例切入

顾客要去饭店吃饭,自助下单,说明要吃什么,数量是多少。下完单以后,顾客就等待该饭店厨师做饭菜,也就是Waiting状态(无限等待状态)。

厨师收到下单信息,开始做饭菜,做好饭菜,把饭菜递到顾客桌面上,顾客看到饭菜已经来了(notify方法),就可以开吃了(等待唤醒机制)。

Java代码实现(线程之间的通信)

分析

创建一个顾客线程:下单,告知厨师要什么菜,菜的数量,调用wait方法,放弃CPU的执行,进入到无限等待状态(Waiting)

创建一个厨师线程:看到下单,花了3秒钟做饭菜,做好之后,调用notify方法,唤醒顾客吃饭了。

注意

顾客线程和厨师线程,必须使用同步代码块包裹起来,保证等待和唤醒只能有一个在执行。

同步使用的锁对象必须保证唯一。

只有锁对象才能够调用Object.wait方法和Object.notify方法。

代码

public class Demo01WaitNotify {
  public static void main(String[] args) {
    // 创建锁对象(要保证锁唯一)
    Object object = new Object();

    // 创建一个顾客线程
    new Thread() {
      @Override
      public void run() {
        // 使用同步代码块包裹起来,保证等待和唤醒只能有一个在执行。
        synchronized (object) {
          // 顾客下单
          System.out.println("我要一个西虹市炒番茄,一个马铃薯炒土豆,两碗米饭");
          // 调用wait方法,放弃CPU的执行,进入到无限等待状态(Waiting)
          try {
            object.wait();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          // 唤醒之后(饭菜上来后),吃饭!!!真香。
          System.out.println("我就是饿死,从这里跳下去,也不会吃你们一口饭。。。真香!!!!");
        }
      }
    }.start();

    // 创建一个厨师线程
    new Thread() {
      @Override
      public void run() {
        // 厨师收到下单请求,花三秒钟把饭菜做好
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        // 使用同步代码块包裹起来,保证等待和唤醒只能有一个在执行。
        synchronized (object) {
          System.out.println("我的饭菜三秒钟做好了,你食唔食哦?");
          // 做好之后,调用notify方法,唤醒顾客吃饭了。
          object.notify();
        }
      }
    }.start();
  }
}

上述内容就是Java中等待唤醒机制的原理是什么,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI