Java的wait(), notify()和notifyAll()使用心得

yizhihongxing

Java 中的 wait(), notify() 和 notifyAll() 方法

介绍

在 Java 中,线程是独立执行的,但是在某些情况下,我们希望线程之间能够进行同步和通信。这时,Java 提供了一些同步机制。其中,使用最广泛的机制就是对象的 wait()、notify() 和 notifyAll() 方法。

线程可以通过调用 wait() 方法来等待某个条件的出现,当条件不满足时,线程将被阻塞。而通过调用 notify() 或 notifyAll() 方法,又可以唤醒等待的线程。

wait() 方法

wait() 方法用于使线程等待某个条件的出现,其语法格式为:

public final void wait() throws InterruptedException

wait() 方法必须在 synchronized 块里调用。当一个线程运行到 wait() 时,它会释放对象的锁,并且线程会进入等待状态。直到另一个线程调用此对象上的 notify() 或 notifyAll() 方法,或者超时时间到期,才能继续执行。

notify() 方法

notify() 方法用于唤醒因等待某个条件而阻塞了的线程,其语法格式为:

public final void notify()

notify() 方法必须在 synchronized 块里调用。当某个线程在等待同一个对象的时候,另外一个使用同一个对象的线程调用 notify() 方法时,等待的线程会从 wait() 方法返回,继续执行。

注意:notify() 方法只能唤醒一个等待线程,具体唤醒哪个线程是随机的,不能确定。因为并不知道哪个线程最需要这个通知。

notifyAll() 方法

notifyAll() 方法用于唤醒因等待某个条件而阻塞了的所有线程,其语法格式为:

public final void notifyAll()

notifyAll() 方法必须在 synchronized 块里调用。当某个线程在等待同一个对象的时候,另外一个使用同一个对象的线程调用 notifyAll() 方法时,所有等待的线程会从 wait() 方法中返回,继续执行。

示例一

下面是一个简单的示例,演示了如何使用 wait() 和 notify() 方法来实现线程间的通信:

public class WaitNotifyDemo {
    public static void main(String[] args) {
        final Object lock = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("Thread 1 is waiting...");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Thread 1 is notified.");
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("Thread 2 is running...");
                    lock.notify();
                }
            }
        });
        t1.start();
        try {
            Thread.sleep(1000); // 等待一秒钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.start();
    }
}

在这个示例中,有两个线程 t1 和 t2,它们使用同一个对象 lock 进行同步。线程 t1 在进入 synchronized 块后调用了 wait() 方法,导致线程被阻塞。而线程 t2 调用了 notify() 方法,唤醒了被阻塞的 t1 线程,使它重新进入就绪状态。

示例二

下面是另一个示例,演示了如何使用 wait() 和 notifyAll() 方法来实现线程间的通信:

public class WaitNotifyAllDemo {
    public static void main(String[] args) {
        final Object lock = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("Thread 1 is waiting...");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Thread 1 is notified.");
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("Thread 2 is waiting...");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("Thread 2 is notified.");
                }
            }
        });
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println("Thread 3 is running...");
                    lock.notifyAll(); // 唤醒所有等待的线程
                }
            }
        });
        t1.start();
        t2.start();
        try {
            Thread.sleep(1000); // 等待一秒钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t3.start();
    }
}

在这个示例中,有三个线程 t1、t2 和 t3,它们使用同一个对象 lock 进行同步。线程 t1 和 t2 在进入 synchronized 块后分别调用了 wait() 方法,导致线程被阻塞。而线程 t3 调用了 notifyAll() 方法,唤醒了所有被阻塞的线程,使它们重新进入就绪状态。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java的wait(), notify()和notifyAll()使用心得 - Python技术站

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

相关文章

  • Springboot jar文件如何打包zip在linux环境运行

    这里就为您详细讲解如何将Spring Boot应用打包成Jar文件并在Linux环境中部署运行。 1. 生成Jar包 在使用Maven进行构建的项目中,我们可以使用以下Maven命令将应用程序打包成可执行的Jar文件: mvn clean package 执行该命令后,Maven将会在target目录下生成一个可执行的Jar包,其名称通常为{artifact…

    Java 2023年5月19日
    00
  • 深入理解Java的Spring框架中的IOC容器

    深入理解Java的Spring框架中的IOC容器 什么是IOC IOC全称 Inversion of Control,即控制反转。它是一种设计模式,用于减少计算机程序的耦合,使程序更加灵活,易于维护和扩展。在计算机程序中,对象之间的关系很密切,一个对象依赖于另一个对象,如果硬编码这些关系,就会造成程序的耦合度很高,不容易维护和扩展。而控制反转就是将这些对象之…

    Java 2023年5月19日
    00
  • Java 数据库连接池Druid 的介绍

    下面我将详细讲解“Java 数据库连接池Druid 的介绍”,分为以下几个方面: Druid 简介 Druid 优势 Druid 的使用 实例演示 1. Druid 简介 Druid 是阿里巴巴开源的一个高效的数据库连接池框架,其功能全面,性能优异,使用方便。Druid 官方提供了界面功能,可以监控数据库连接和 SQL 调用等信息。 Druid 提供以下功能…

    Java 2023年5月19日
    00
  • JSP之表单提交get和post的区别详解及实例

    JSP之表单提交get和post的区别详解及实例 在JSP中,表单可以使用get和post两种方法提交。本攻略将详细讲述两种方法的区别以及使用实例。 GET和POST的区别 GET方法将数据追加在URL末尾,而POST方法将数据放在HTTP请求的正文中。因此,使用GET方法提交的数据将被显示在URL中,而POST方法提交的数据不会在URL中显示。 由于数据被…

    Java 2023年6月15日
    00
  • Spring Boot 与 mybatis配置方法

    接下来我将为您详细讲解如何使用Spring Boot和Mybatis进行配置,以下是完整攻略。 1. 引入mybatis-spring-boot-starter 在使用Spring Boot和Mybatis进行配置之前,我们需要引入mybatis-spring-boot-starter,这是一个Mybatis的Spring Boot自动配置模块,可以帮我们简…

    Java 2023年5月20日
    00
  • Java窗口精细全方位讲解

    Java窗口精细全方位讲解 简介 本篇攻略将完整讲解如何用Java语言创建窗口并增加各种控件,包括文本框、按钮、下拉框等等,并讲解如何实现它们的交互功能。 准备工作 在开始编程前,你需要安装Java开发工具包(JDK)和一个编译器,比如Eclipse或者IntelliJ IDEA。这里我们以Eclipse为例。 创建窗口 要创建窗口,我们需要创建一个新的Ja…

    Java 2023年5月23日
    00
  • dockerfile-maven-plugin极简教程(推荐)

    下面是“dockerfile-maven-plugin极简教程(推荐)”的完整攻略: 1. 简介 dockerfile-maven-plugin是一个maven插件,可以将maven项目构建成Docker镜像。通过dockerfile-maven-plugin,我们可以将应用程序打包成Docker镜像并快速部署。 2. 安装 在pom.xml文件中添加以下依…

    Java 2023年5月20日
    00
  • [PHP]模板引擎Smarty深入浅出介绍

    非常感谢您对我的专业知识的关注,以下是“[PHP]模板引擎Smarty深入浅出介绍”的完整攻略。 什么是Smarty Smarty 是一种 PHP 模板引擎,它是开源的、免费的、遵循 LGPL 协议发布的软件。Smarty 的目标是使设计师和程序员可以相互协作,它对模板的语法进行了规范定义并且大大降低了 PHP 代码在模板中出现的频率,从而使得代码更加易于阅…

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