在Java中,多线程编程是一种常见的方式,可以让程序更高效地运行。为了有效地控制线程之间的协作,Java提供了等待唤醒机制(即wait()notify()方法)。这使得一个线程可以在某种条件不满足时暂停执行,并在其他线程满足条件时被唤醒执行。

等待唤醒机制的基本原理

在Java中,wait()notify()方法是定义在Object类中,因此任何Java对象都可以作为锁。通过这些方法,线程可以在某种条件下挂起,直到其他线程调用同一个对象的notify()notifyAll()方法将其唤醒。

wait() 方法

当一个线程调用wait()方法时,它会释放当前对象的监视器锁,并进入等待状态,直到其他线程调用该对象的notify()notifyAll()方法。需要注意的是,wait()方法必须在同步代码块中调用。

notify() 方法

notify()方法用于唤醒在此对象监视器上等待的单个线程。如果有多个线程在等待,Java会选择一个线程唤醒。notifyAll()则会唤醒所有等待的线程。

代码示例

下面是一个简单的生产者-消费者模型的示例,展示如何使用wait()notify()来实现等待唤醒机制。

import java.util.LinkedList;
import java.util.Queue;

class DataBuffer {
    private final Queue<Integer> buffer = new LinkedList<>();
    private final int limit = 10;

    public synchronized void produce(int value) throws InterruptedException {
        // 如果缓冲区满,则等待
        while (buffer.size() == limit) {
            wait();
        }
        buffer.add(value);
        System.out.println("生产者生产: " + value);
        // 通知消费者可以消费
        notify();
    }

    public synchronized int consume() throws InterruptedException {
        // 如果缓冲区为空,则等待
        while (buffer.isEmpty()) {
            wait();
        }
        int value = buffer.poll();
        System.out.println("消费者消费: " + value);
        // 通知生产者可以生产
        notify();
        return value;
    }
}

class Producer implements Runnable {
    private final DataBuffer dataBuffer;

    public Producer(DataBuffer dataBuffer) {
        this.dataBuffer = dataBuffer;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 20; i++) {
                dataBuffer.produce(i);
                Thread.sleep(100); // 模拟生产时间
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

class Consumer implements Runnable {
    private final DataBuffer dataBuffer;

    public Consumer(DataBuffer dataBuffer) {
        this.dataBuffer = dataBuffer;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 20; i++) {
                dataBuffer.consume();
                Thread.sleep(150); // 模拟消费时间
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public class WaitNotifyExample {
    public static void main(String[] args) {
        DataBuffer dataBuffer = new DataBuffer();
        Thread producerThread = new Thread(new Producer(dataBuffer));
        Thread consumerThread = new Thread(new Consumer(dataBuffer));

        producerThread.start();
        consumerThread.start();

        try {
            producerThread.join();
            consumerThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

代码解析

  1. 数据缓冲区(DataBuffer):这是生产者和消费者共享的资源,使用一个 Queue(队列)来存储数据,限制其大小(limit = 10)。

  2. 生产者(Producer):不断产生数据,将其放入缓冲区。如果缓冲区满,则调用wait()方法进入等待状态,直到消费者消费了某些数据并调用notify()唤醒生产者。

  3. 消费者(Consumer):不断从缓冲区消费数据。如果缓冲区为空,则调用wait()方法进入等待状态,直到生产者生产了数据并调用notify()唤醒消费者。

  4. 主程序(main 方法):创建生产者和消费者线程,启动后,主程序等待这两个线程完成。

结论

通过使用wait()notify()方法,Java程序设计者可以实现复杂的线程协作机制,将多个线程之间的关系管理得更加高效与清晰。这个机制在实际开发中随处可见,比如服务器的任务调度、数据处理等场景中都有其身影。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部