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 多线程程序的性能和可靠性。

相关推荐
冷雨夜中漫步4 小时前
Python快速入门(6)——for/if/while语句
开发语言·经验分享·笔记·python
JH30735 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
m0_736919106 小时前
C++代码风格检查工具
开发语言·c++·算法
Coder_Boy_6 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
2501_944934736 小时前
高职大数据技术专业,CDA和Python认证优先考哪个?
大数据·开发语言·python
invicinble6 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟7 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖7 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
2301_763472468 小时前
C++20概念(Concepts)入门指南
开发语言·c++·算法
TechWJ8 小时前
PyPTO编程范式深度解读:让NPU开发像写Python一样简单
开发语言·python·cann·pypto