Java中的wait和await

在Java中,wait和await是两个用于线程同步的关键字。它们的作用是类似的,都是用于线程之间的通信和协调。然而,它们的使用方式和适用场景有所不同。本文将详细介绍wait和await的用法,并给出相应的代码示例。

1. wait

在Java中,wait是Object类的一个方法,用于暂停当前线程,并释放持有的锁。它通常与synchronized关键字一起使用,用于实现线程间的等待和通知机制。

当一个线程执行wait方法时,它会进入等待状态,并释放对象的锁。其他线程可以获取该对象的锁,并执行相应的操作。当某个条件满足时,调用notify或notifyAll方法来唤醒等待的线程。被唤醒的线程会重新尝试获取对象的锁,并继续执行。

下面是一个简单的示例,演示了wait和notify的使用:

class Message {
    private String content;
    private boolean available = false;

    public synchronized String read() {
        while (!available) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        available = false;
        notifyAll();
        return content;
    }

    public synchronized void write(String message) {
        while (available) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        content = message;
        available = true;
        notifyAll();
    }
}

class Reader implements Runnable {
    private Message message;

    public Reader(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        String receivedMessage = message.read();
        System.out.println("Received: " + receivedMessage);
    }
}

class Writer implements Runnable {
    private Message message;

    public Writer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        String messageContent = "Hello World!";
        message.write(messageContent);
        System.out.println("Sent: " + messageContent);
    }
}

public class WaitExample {
    public static void main(String[] args) {
        Message message = new Message();
        Thread readerThread = new Thread(new Reader(message));
        Thread writerThread = new Thread(new Writer(message));

        readerThread.start();
        writerThread.start();
    }
}

在上面的示例中,Message类表示一个消息对象,它具有read和write方法用于读取和写入消息。这两个方法都使用了synchronized关键字,并使用wait和notifyAll方法实现了等待和通知机制。

Reader类和Writer类分别表示读取线程和写入线程。当写入线程写入消息后,它会唤醒等待的读取线程。读取线程在读取消息之前会等待,直到有消息可读。

2. await

在Java中,await是在并发包(java.util.concurrent)中的一个方法,用于线程之间的等待和协作。它通常与Condition对象一起使用,用于实现更复杂的线程同步控制。

Condition是一个在Lock对象上创建的等待/通知机制。与传统的synchronized和wait/notify相比,Condition提供了更多的灵活性和功能。

下面是一个使用await和signal的示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class SharedData {
    private int count = 0;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void increment() {
        lock.lock();
        try {
            count++;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void waitForCount(int target) {
        lock.lock();
        try {
            while (count < target) {
                condition.await();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }
}

class Incrementer implements Runnable {
    private SharedData sharedData;

    public Incrementer(SharedData sharedData) {
        this.sharedData = sharedData;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            sharedData.increment();
            System.out.println("Incremented: " + sharedData.getCount());
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }