wait,notify,notifyAll用法解析

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 在并发开发中,锁是非常常见的,而wait/notify也经常会和锁一起使用,例如在生产者消费者模式中。而且wait/notify也必须和锁一起使用,因为它们都是基于对象的,否则会抛出异常。

在并发开发中,锁是非常常见的,而wait/notify也经常会和锁一起使用,例如在生产者消费者模式中。而且wait/notify也必须和锁一起使用,因为它们都是基于对象的,否则会抛出异常。
下面,我们通过一段简单的代码,来了解以下wait/notify的用法:

public class WaitNotifyTest {

    public static final Object FINAL_OBJECT = new Object();
    static class R implements Runnable{

        @Override
        public void run() {
            synchronized (FINAL_OBJECT) {
                try {
                    System.out.println(Thread.currentThread().getName()+"进入wait");
                    FINAL_OBJECT.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"运行完成");
        }
    }

    public static void main(String[] args) throws InterruptedException {

        for (int i = 0; i < 3; i++) {
            new Thread(new R()).start();
        }
        Thread.sleep(100);
        synchronized (FINAL_OBJECT) {
            FINAL_OBJECT.notify();
        }
    }

}

运行结果如下:

Thread-2进入wait
Thread-4进入wait
Thread-3进入wait
Thread-2运行完成

我们发现,线程2运行完成之后,线程3和线程4还是继续会等待,所以notify方法只会唤醒一个进入wait的线程,并且是第一个进入的。如果使用notifyAll,运行结果如下:

Thread-2进入wait
Thread-3进入wait
Thread-4进入wait
Thread-4运行完成
Thread-2运行完成
Thread-3运行完成

由此我们可以分析出:使用notifyAll会将所有的线程都唤醒,唤醒之后,谁先获取到CPU资源,谁就先执行,所以这三个线程的执行顺序出现了变化。
而且,通过以上代码,我们可以知道wait的一个特性:当线程进入wait状态时,该线程会将锁资源释放,其他的线程就可以进来,而当它再次被唤醒时,就可以再次去抢夺锁资源了。

目录
相关文章
|
2月前
|
关系型数据库 TensorFlow 算法框架/工具
Docker技术概论(4):Docker CLI 基本用法解析
Docker技术概论(4):Docker CLI 基本用法解析
153 1
|
9天前
|
安全 网络安全 开发工具
深入探索Git:全面解析Git的用法与最佳实践
深入探索Git:全面解析Git的用法与最佳实践
28 2
|
2月前
|
数据采集 运维 监控
运维笔记:流编辑器sed命令用法解析
运维笔记:流编辑器sed命令用法解析
47 5
|
2月前
|
Java Spring
🔥JSF 与 Spring 强强联手:打造高效、灵活的 Web 应用新标杆!💪 你还不知道吗?
【8月更文挑战第31天】JavaServer Faces(JSF)与 Spring 框架是常用的 Java Web 技术。本文介绍如何整合两者,发挥各自优势,构建高效灵活的 Web 应用。首先通过 `web.xml` 和 `ContextLoaderListener` 配置 Spring 上下文,在 `applicationContext.xml` 定义 Bean。接着使用 `@Autowired` 将 Spring 管理的 Bean 注入到 JSF 管理的 Bean 中。
39 0
|
2月前
|
JavaScript 前端开发 开发者
深入解析Angular装饰器:揭秘框架核心机制与应用——从基础用法到内部原理的全面教程
【8月更文挑战第31天】本文深入解析了Angular框架中的装饰器特性,包括其基本概念、使用方法及内部机制。装饰器作为TypeScript的关键特性,在Angular中用于定义组件、服务等。通过具体示例介绍了`@Component`和`@Injectable`装饰器的应用,展示了如何利用装饰器优化代码结构与依赖注入,帮助开发者构建高效、可维护的应用。
24 0
|
2月前
|
存储 运维 监控
运维.Linux下执行定时任务(上:Cron简介与用法解析)
运维.Linux下执行定时任务(上:Cron简介与用法解析)
41 0
|
3月前
|
并行计算 Java 开发者
解析Java中的Lambda表达式用法
解析Java中的Lambda表达式用法
|
2月前
|
监控 网络协议 Java
Tomcat源码解析】整体架构组成及核心组件
Tomcat,原名Catalina,是一款优雅轻盈的Web服务器,自4.x版本起扩展了JSP、EL等功能,超越了单纯的Servlet容器范畴。Servlet是Sun公司为Java编程Web应用制定的规范,Tomcat作为Servlet容器,负责构建Request与Response对象,并执行业务逻辑。
Tomcat源码解析】整体架构组成及核心组件
|
2月前
|
存储 NoSQL Redis
redis 6源码解析之 object
redis 6源码解析之 object
58 6
|
25天前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
什么是线程池?从底层源码入手,深度解析线程池的工作原理

热门文章

最新文章

推荐镜像

更多