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

相关推荐
yurenpai(27届找实习中)8 分钟前
redis_点评(25.附件店铺—把数据库里的店铺按【类型分组】,批量导入Redis 的 GEO 地理位置结构)
java·redis·缓存
云烟成雨TD16 分钟前
Spring AI Alibaba 1.x 系列【66】Graph 长期记忆
java·人工智能·spring
Javatutouhouduan32 分钟前
Java面试大厂真题汇总!
java·java面试·java面试题·后端开发·java编程·java架构师·java八股文
maomao大哥闯天下41 分钟前
K8s对象deployment、job、service应用详解
java·容器·kubernetes
闪电悠米43 分钟前
黑马点评-优惠券秒杀-05_local_lock_cluster_problem
java·spring boot·redis·缓存
IronMurphy1 小时前
SSM拷打第二讲!!!
java·spring·mybatis
Hanniel1 小时前
Python 元类(下):进阶与实战建议
开发语言·python
小江的记录本1 小时前
【JVM虚拟机】类加载机制:类加载全流程:加载→验证→准备→解析→初始化(附《思维导图》+《面试高频考点清单》)
java·jvm·spring boot·算法·安全·spring·面试
会编程的土豆1 小时前
Go interface 底层的 itab 到底是什么
开发语言·后端·golang
千纸鹤の脉搏1 小时前
多线程的初步了解---进程与线程
java·开发语言·学习·线程