Java锁等待唤醒机制

在 Java 并发编程中,锁的等待和唤醒机制至关重要,通常使用 wait()notify()notifyAll() 来实现线程间的协调。本文将详细介绍这些方法的用法,并通过示例代码加以说明。

1. wait()notify()notifyAll()

在 Java 中,Object 类提供了 wait()notify()notifyAll() 方法,它们用于线程间的通信。

  • wait():使当前线程进入等待状态,并释放锁。
  • notify():唤醒单个等待线程。
  • notifyAll():唤醒所有等待线程。

注意,这些方法必须在同步代码块(synchronized)中调用,否则会抛出 IllegalMonitorStateException

2. 示例代码

下面的示例展示了 wait()notify() 的使用。

复制代码
class SharedResource {
    private boolean available = false;
    
    public synchronized void produce() {
        while (available) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        System.out.println("Producing an item");
        available = true;
        notify();
    }
    
    public synchronized void consume() {
        while (!available) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        System.out.println("Consuming an item");
        available = false;
        notify();
    }
}

public class WaitNotifyExample {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();
        
        Thread producer = new Thread(resource::produce);
        Thread consumer = new Thread(resource::consume);
        
        producer.start();
        consumer.start();
    }
}

3. wait()notify() 的工作原理

  1. 生产者线程 produce()availabletrue 时调用 wait() 进入等待状态,释放锁。
  2. 消费者线程 consume()availablefalse 时调用 wait() 进入等待状态,释放锁。
  3. produce() 生产后调用 notify() 唤醒 consume()
  4. consume() 消费后调用 notify() 唤醒 produce()

4. notifyAll() 的使用场景

notify() 仅唤醒一个线程,而 notifyAll() 可用于有多个等待线程的情况,以防止某些线程被永久阻塞。

复制代码
public synchronized void produce() {
    while (available) {
        try {
            wait();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    System.out.println("Producing an item");
    available = true;
    notifyAll();
}

5. LockCondition 方式

除了 synchronized,还可以使用 LockCondition 进行等待和唤醒控制。

复制代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class SharedResourceWithLock {
    private boolean available = false;
    private final Lock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    
    public void produce() {
        lock.lock();
        try {
            while (available) {
                condition.await();
            }
            System.out.println("Producing an item");
            available = true;
            condition.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
    
    public void consume() {
        lock.lock();
        try {
            while (!available) {
                condition.await();
            }
            System.out.println("Consuming an item");
            available = false;
            condition.signal();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
}

6. 总结

  • wait()notify() 需要在 synchronized 块中使用。
  • notifyAll() 可防止线程被永久阻塞。
  • LockCondition 提供更灵活的等待和唤醒机制。

合理使用这些机制可以提升 Java 多线程程序的性能和可靠性。

相关推荐
Dovis(誓平步青云)10 分钟前
牛奶不能减成负数:冰箱库存的筛选、去重与不可变更新
android·java·开发语言
OPEN-F11 分钟前
Python进阶教程:算法与数据结构入门
开发语言·python
薛定猫AI21 分钟前
【技术干货】Claude Code多模型代理与反馈闭环:Python实现可验证的AI编程工作流
开发语言·python·ai编程
XR12345678823 分钟前
工厂车间无线网络怎么选?AGV 与复杂环境是分水岭
开发语言·php
zq_638929 分钟前
利用 MATLAB 调用 STK Object Model COM 显示雷达受干扰前后探测范围的变化
开发语言·matlab
大黄说说43 分钟前
类型安全时代:PHP 8+ 的联合类型、交集类型与泛型(模板)最佳实践
开发语言·安全·php
SWAGGY..1 小时前
【C++初阶】:(15)模板进阶--从非类型参数到模板特化与分离编译
java·服务器·前端
小弥儿1 小时前
GPT Image 2 提示词库,把散落的生图提示词变成工程资产
开发语言·javascript·gpt·学习
楠楠子呀1 小时前
独立站聊天转化全链路:从二维码引流到数据复盘
java·javascript·数据仓库·python·c#·自动化·etl
yurenpai(27届找实习中)1 小时前
从零读懂AI智能客服(二):Java 多模块项目如何协作:Maven 依赖、Spring 注入与运行时装配
java·spring·maven