首页 > 编程语言 >在Java中如何使用wait()和notify()方法

在Java中如何使用wait()和notify()方法

时间:2025-01-08 16:00:57浏览次数:3  
标签:调用 Java lock 线程 notify 唤醒 wait

在Java中,wait()notify()方法是用于线程间通信的重要同步机制。它们主要用于协调多个线程对共享资源的访问,确保线程安全。以下是对这两个方法的详细解释和使用场景说明:

1. wait()方法

定义

wait()方法使当前线程进入等待状态,直到其他线程调用此对象的notify()notifyAll()方法。当一个线程调用wait()时,它会释放该对象上的锁,并进入等待队列,直到被唤醒。

使用场景
  • 生产者-消费者模型:在生产者-消费者模型中,生产者线程生产数据后调用notify()通知消费者线程可以消费数据;消费者线程在没有数据可消费时调用wait()进入等待状态。
  • 任务调度:在某些任务调度系统中,某些任务可能需要等待特定条件满足后再继续执行,这时可以使用wait()让线程进入等待状态,直到条件满足时再被唤醒。

2. notify()方法

定义

notify()方法用于唤醒在此对象监视器上等待的单个线程。如果有多个线程在等待,则选择其中一个进行唤醒。被唤醒的线程将尝试重新获得对象的锁,并在成功获取锁后继续执行。

使用场景
  • 资源竞争:在多线程环境下,当某个线程完成了对共享资源的操作并释放了锁,它可以调用notify()来唤醒等待该资源的线程。
  • 事件驱动:在某些事件驱动的系统中,当某个事件发生时,可以调用notify()来通知等待该事件的线程进行处理。

3. 同步块内使用

定义

wait()notify()必须在同步块或同步方法内部使用。这是因为这些方法依赖于对象的内置锁(也称为监视器锁),而只有持有锁的线程才能调用这些方法。

使用场景
  • 保护临界区:在多线程编程中,临界区是一段需要互斥访问的代码。通过在同步块中使用wait()notify(),可以确保同一时间只有一个线程能够执行临界区内的代码。
  • 线程协作:在需要多个线程协作完成某项任务的场景下,可以使用wait()notify()来实现线程间的协调。

4. 释放锁

定义

调用wait()会释放锁,而调用notify()不会释放锁。这意味着在调用wait()之后,当前线程会释放它持有的锁,并进入等待状态;而在调用notify()之后,当前线程仍然持有锁,直到它退出同步块或同步方法。

使用场景
  • 避免死锁:通过在调用wait()时释放锁,可以避免死锁的发生。因为如果线程在持有锁的情况下进入等待状态,其他线程就无法获取锁,从而导致死锁。
  • 提高并发性:通过在调用notify()时不释放锁,可以提高系统的并发性。因为被唤醒的线程可以直接继续执行,而不需要重新竞争锁。

示例代码

以下是一个使用wait()notify()方法的简单示例,展示了生产者-消费者模型的基本实现:

public class ProducerConsumerExample {
    private static final Object lock = new Object();
    private static boolean condition = false;
    private static int item = 0;

    public static void main(String[] args) throws InterruptedException {
        Thread producer = new Thread(() -> {
            synchronized (lock) {
                while (true) {
                    while (condition) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    item++;
                    System.out.println("Produced: " + item);
                    condition = true;
                    lock.notify();
                }
            }
        });

        Thread consumer = new Thread(() -> {
            synchronized (lock) {
                while (true) {
                    while (!condition) {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("Consumed: " + item);
                    condition = false;
                    lock.notify();
                }
            }
        });

        producer.start();
        consumer.start();
    }
}

在这个示例中,生产者线程和消费者线程通过共享的lock对象进行同步。生产者线程在生产完一个项目后调用notify()唤醒消费者线程;消费者线程在消费完一个项目后调用notify()唤醒生产者线程。通过这种方式,实现了生产者和消费者之间的协调和通信。

标签:调用,Java,lock,线程,notify,唤醒,wait
From: https://blog.csdn.net/luohuahui2012/article/details/145011434

相关文章

  • Java HashMap 深度解析:底层原理、源码剖析与面试必备知识
    1.HashMap概述HashMap是Java集合框架中最常用的数据结构之一,基于哈希表(HashTable)实现。它以键值对(Key-Value)存储数据,允许null键和null值,且无序。1.1HashMap的特性基于哈希表(HashTable)实现允许null键和null值非线程安全默认初始容量16,负载因子0.75JDK1......
  • 机房预约系统|Java|SSM|JSP|
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 即动运动系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • 汉服文化管理系统|Java|SSM|VUE| 前后端分离
                 【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetomcat......
  • Java8 日期/时间 工具类
    importorg.apache.commons.lang3.StringUtils;importjava.text.SimpleDateFormat;importjava.time.*;importjava.time.format.DateTimeFormatter;importjava.time.temporal.ChronoUnit;importjava.time.temporal.TemporalAdjusters;importjava.util.Date;impor......
  • 史上最全java面试题之JAVA笔试题汇总
    什么是Java程序的主类?应用程序和小程序的主类有何不同?一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main()方法的类。而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。应用程序的主类不一定要求是public类,但小程序的主类......
  • 利用 Java 爬虫获取淘宝商品详情 API 接口的长篇软文
    在当今数字化时代,电子商务蓬勃发展,淘宝作为国内领先的电商平台,汇聚了海量商品信息。对于企业、开发者以及市场研究人员来说,能够获取淘宝商品的详细信息,对于市场分析、产品定价、竞品研究等方面具有重要意义。然而,淘宝官方提供的API接口往往存在一定的限制,如请求频率限制、数据字......
  • javascript-chapter11 标准库
    1.setclassset是值的集合,set是无序的,且不能重复。一个值可以是或不是集合的成员。lets=newSet();//空集lett=newSet([1,s]);//有两个元素的集合。lett=newSet(s);//新集合,元素来自于sletunique=newSet("Mississippi");//Misp四个元素unique.size//4Set不用在使......
  • Java从零到1的开始-Day06
    一、方法1.参数和返回值使用的时机1.参数: 当想将一个方法中的数据传递到另外一个方法中,那么被调用方法需要定义参数,调用时传递想要传递过去的数据2.返回值: 调用方法时,想要此方法的结果,去参与其他操作,那么被调用的方法需要将自己的结果返回publicclassDemo0......
  • 字节青训入营考核十五题-Java-创意标题匹配问题
    问题问题描述在广告平台中,为了给广告主一定的自由性和效率,允许广告主在创造标题的时候以通配符的方式进行创意提交。线上服务的时候,会根据用户的搜索词触发的bidword对创意中的通配符(通配符是用成对{}括起来的字符串,可以包含0个或者多个字符)进行替换,用来提升广告投放体......