ITPub博客

首页 > 应用开发 > Java > java中如何使用 wait() 和 notify()?

java中如何使用 wait() 和 notify()?

Java 作者:爬格子PA 时间:2024-12-04 15:26:00 0 删除 编辑

在 Java 中,wait() 和 notify() 是用于线程间通信的重要方法。它们属于 Object 类,而不是 Thread 类,因为它们操作的是共享对象的监视器(monitor)。以下是它们的用法以及需要注意的事项。
基本概念

    wait() 方法:
        让当前线程进入等待状态,并释放它持有的对象锁。
        必须在同步代码块或同步方法中调用,否则会抛出 IllegalMonitorStateException。
        等待线程可以被其他线程通过 notify() 或 notifyAll() 唤醒。

    notify() 方法:
        唤醒一个正在等待该对象锁的线程。
        如果有多个线程等待,具体唤醒哪一个线程由 JVM 决定。

    notifyAll() 方法:
        唤醒所有等待该对象锁的线程。

示例代码
生产者-消费者问题

下面是使用 wait() 和 notify() 实现的生产者-消费者模型。

class SharedResource {
    private int data;
    private boolean isProduced = false;

    // 生产数据
    public synchronized void produce(int value) throws InterruptedException {
        while (isProduced) {
            wait(); // 等待消费完毕
        }
        data = value;
        System.out.println("Produced: " + value);
        isProduced = true;
        notify(); // 通知消费者
    }

    // 消费数据
    public synchronized int consume() throws InterruptedException {
        while (!isProduced) {
            wait(); // 等待生产
        }
        System.out.println("Consumed: " + data);
        isProduced = false;
        notify(); // 通知生产者
        return data;
    }
}

public class ProducerConsumerDemo {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();

        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    resource.produce(i);
                    Thread.sleep(100); // 模拟生产延迟
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    resource.consume();
                    Thread.sleep(200); // 模拟消费延迟
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

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

运行步骤

    启动线程:生产者和消费者线程交替运行。
    线程通信:生产者调用 wait() 等待消费者消费完毕;消费者调用 wait() 等待生产者生产数据。
    锁和同步:synchronized 关键字确保了线程安全。

注意事项

    wait() 和 notify() 必须在同步块中使用:

    synchronized (obj) {
        obj.wait();
    }

    否则会抛出 IllegalMonitorStateException。

    释放锁:
        调用 wait() 后,线程会释放锁,进入等待队列。
        被 notify() 唤醒后,线程会尝试重新获取锁并继续执行。

    死锁风险:
        小心使用 wait() 和 notify(),避免逻辑错误导致死锁。

    用 notifyAll() 替代 notify()(视情况而定):
        如果多个线程在等待相同的对象,使用 notify() 可能会导致某些线程永远得不到唤醒。
        notifyAll() 更加安全,但可能降低效率。

推荐替代方案

对于现代 Java 开发,可以使用更高级的并发工具,比如:

    BlockingQueue:用于生产者-消费者模型。
    Condition:提供类似 wait() 和 notify() 的功能,但更灵活。
    CountDownLatch 和 Semaphore:适用于更复杂的线程间协调需求。

wait() 和 notify() 更接近底层,在简单场景中足够,但高并发场景下推荐使用 java.util.concurrent 提供的工具。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70040412/viewspace-3051216/

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70042566/viewspace-3054640/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
爱好作词作曲,喜看文章!

注册时间:2024-11-27

  • 博文量
    44
  • 访问量
    55884