JUC中的wait与notify方法实现原理详解

JUC中的wait与notify方法实现原理详解

JUC(Java Util Concurrent)是Java中用于处理多线程编程的库,其中包含了大量的线程处理类,其中常用的类之一是Object类中的wait方法和notify方法。本文将详细讲解JUC中的wait与notify方法实现原理。

wait方法的实现原理

wait方法是Object类中的一个方法,表示让线程等待,直到其他线程中断或唤醒该线程。其实现原理是让调用wait方法的线程进入等待队列(WaitSet),并且将线程状态设置为等待状态(WAITING或TIMED_WAITING)。等待队列中的线程等待被唤醒,唤醒机制由notify方法实现。

具体实现过程可以分为下面三个步骤:

1.当前线程进入等待队列,释放当前对象的锁(如果有的话)。

2.当有其他线程调用该对象的notify/notifyAll方法并持有了该对象的锁时,等待队列中的线程就会被唤醒,开始竞争锁。

3.当某个线程竞争成功后会从等待队列中移除,继续执行下面的逻辑。

wait方法的使用示例:

public class WaitTest {
    public synchronized void waitMethod() {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting");
            Thread.sleep(1000);
            wait(); // 调用wait方法,释放当前对象锁
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void notifyMethod() {
        System.out.println(Thread.currentThread().getName() + "开始通知所有等待的线程");
        notifyAll(); // 调用notifyAll方法唤醒等待队列中的所有线程
    }
}

public class WaitNotifyDemo {
    public static void main(String[] args) {
        WaitTest waitTest = new WaitTest();
        Runnable waitTask = () -> waitTest.waitMethod();
        Runnable notifyTask = () -> waitTest.notifyMethod();
        new Thread(waitTask, "线程1").start();
        new Thread(waitTask, "线程2").start();
        new Thread(notifyTask, "线程3").start();
    }
}

notify方法的实现原理

notify方法是Object类中的一个方法,表示唤醒在等待队列中的一个线程,让它可以继续执行,该方法必须在同步方法块或同步方法中使用。其实现原理是通过唤醒等待队列(WaitSet)中的一个线程,该线程从等待队列中移除并重新加入运行队列(RunSet)。

具体实现过程可以分为下面三个步骤:

1.当前线程通知等待队列中的一个线程。

2.通知的线程由等待队列移到运行队列中。

3.线程运行后会经过CPU调度器的调度。

notify方法的使用示例:

public class WaitTest {
    public synchronized void waitMethod() {
        try {
            System.out.println(Thread.currentThread().getName() + " is waiting");
            Thread.sleep(1000);
            wait(); // 调用wait方法,释放当前对象锁
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void notifyMethod() {
        System.out.println(Thread.currentThread().getName() + "开始通知等待的线程");
        notify(); // 调用notify方法唤醒等待队列中的一个线程
    }
}

public class WaitNotifyDemo {
    public static void main(String[] args) {
        WaitTest waitTest = new WaitTest();
        Runnable waitTask = () -> waitTest.waitMethod();
        Runnable notifyTask = () -> waitTest.notifyMethod();
        new Thread(waitTask, "线程1").start();
        new Thread(waitTask, "线程2").start();
        new Thread(notifyTask, "线程3").start();
    }
}

以上就是JUC中wait与notify方法实现原理的详细讲解。通过这篇攻略,您可以更深入地了解JUC中的线程处理机制,以便更好地处理多线程编程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JUC中的wait与notify方法实现原理详解 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • IDEA中编写并运行shell脚本的实现

    下面是“IDEA中编写并运行shell脚本的实现”的完整攻略: 环境准备 首先,我们需要安装好以下工具: JDK 8或以上版本 IDEA IDE Linux操作系统 创建项目 在IDEA中,我们可以创建一个简单的Java项目来实现编写并运行shell脚本的目的。具体步骤如下: 在IDEA中打开File菜单,选择New->Project。 在弹出的窗口中…

    Java 2023年6月1日
    00
  • springboot拦截器过滤token,并返回结果及异常处理操作

    下面我将为你详细讲解如何使用Spring Boot实现拦截器过滤Token并返回结果及异常处理操作。 什么是拦截器及Token认证 在Spring Boot中,拦截器是一种非常常用的组件,它可以拦截请求,进行一些处理,并执行相应的操作。Token认证是指在用户登录成功后,服务器会生成一个Token并返回给客户端,客户端在以后的请求中携带这个Token用于鉴权…

    Java 2023年5月19日
    00
  • 使用idea和gradle编译spring5源码的方法步骤

    下面就是详细的“使用idea和gradle编译spring5源码的方法步骤”的攻略: 1.准备工具 首先,我们需要准备好以下工具: JDK IDEA Gradle Spring5源码 具体版本根据自己的需求来选择,这里不再赘述。 2.导入Spring5源码 将Spring5源码下载下来,并用IDEA导入项目。如果是第一次使用Gradle编译该项目,需要等待I…

    Java 2023年5月26日
    00
  • Jsp中解决session过期跳转到登陆页面并跳出iframe框架的方法

    前言: 在JSP应用中,session过期是一个比较常见的问题。如果session过期后用户还要操作应用,那么应用最好将用户跳转到登陆页面重新登录。但有时候,我们的应用页面嵌套在iframe中,而session过期后,如果直接跳转会导致页面跳出iframe,变得丑陋,影响用户体验。因此,本篇攻略就来介绍一种可行的方法,可以在session过期后跳转到登录页面…

    Java 2023年6月15日
    00
  • Java Kafka实现延迟队列的示例代码

    下面我来详细讲解Java Kafka实现延迟队列的示例代码的完整攻略。 什么是延迟队列 延迟队列是一种可以在一段时间之后才能被消费者消费的消息队列。它通常会使用时间优先级来控制消息的消费顺序,这种机制被称为TTL(Time To Live)。常见的应用场景是延迟发送提醒、定时任务等。 实现延迟队列的方式 实现延迟队列的方式有很多种,Kafka也提供了两种实现…

    Java 2023年6月2日
    00
  • Tomcat使用Log4j输出catalina.out日志

    介绍 在使用Tomcat服务器时,通常需要对服务器的运行状态进行特定的记录,例如:访问日志、错误日志、调试日志等。而catalina.out则是Tomcat服务中的一种重要的日志文件,其中一般会记录Tomcat服务器的所有日志,包括控制台的输出信息、访问日志、错误日志等。在Tomcat服务器中,默认的日志实现是JUL(Java Util Logging),但…

    Java 2023年5月19日
    00
  • 解决JDBC的class.forName()问题

    解决 JDBC 的 Class.forName() 问题 在使用 JDBC 连接数据库时,我们通常使用的是以下代码: Class.forName("com.mysql.cj.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, username, passwor…

    Java 2023年6月16日
    00
  • Struts2相关的面试题整理分享

    下面是Struts2相关的面试题整理分享的完整攻略。 1. Struts2简介 Struts2是一个基于MVC设计模式的Web开发框架,它基于Java Servlet技术,可以帮助开发者更方便地创建Web应用程序。 1.1 MVC架构 MVC架构将应用程序分为3个主要部分: Model:应用程序数据及其处理 View:用户界面的展示 Controller:接…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部