欢迎访问宙启技术站
智能推送

使用wait()函数实现线程的等待和唤醒实例分析

发布时间:2024-01-02 15:43:41

在Java中,可以使用wait()函数实现线程的等待和唤醒。wait()函数是Object类中的一个方法,它使当前线程进入等待状态,直到其他线程调用notify()或notifyAll()方法唤醒它。

要使用wait()函数,需要满足以下几个条件:

1. wait()函数必须在同步代码块中调用,即必须先获得对象的锁。

2. wait()函数会释放对象的锁,使得其他线程可以进入同步代码块。

3. wait()函数会将线程放入等待队列中,直到其他线程调用notify()或notifyAll()方法将其唤醒。

4. wait()函数可以通过指定等待的时间来设置超时。

下面通过一个简单的例子来说明如何使用wait()函数实现线程的等待和唤醒。

public class WaitNotifyExample {
    public static void main(String[] args) {
        Message message = new Message(); // 创建一个共享的消息对象

        Thread senderThread = new Thread(new Sender(message)); // 创建一个发送线程
        Thread receiverThread = new Thread(new Receiver(message)); // 创建一个接收线程

        senderThread.start(); // 启动发送线程
        receiverThread.start(); // 启动接收线程
    }
}

class Message {
    private String content;
    private boolean isEmpty = true;

    public synchronized String getContent() {
        while (isEmpty) { // 如果内容为空,则等待
            try {
                wait(); // 线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isEmpty = true; // 设置内容为空
        notifyAll(); // 唤醒其他等待的线程
        return content;
    }

    public synchronized void setContent(String content) {
        while (!isEmpty) { // 如果内容不为空,则等待
            try {
                wait(); // 线程等待
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        isEmpty = false; // 设置内容不为空
        this.content = content;
        notifyAll(); // 唤醒其他等待的线程
    }
}

class Sender implements Runnable {
    private Message message;

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

    @Override
    public void run() {
        String[] messages = {"Hello", "World", "Goodbye"};
        for (String m : messages) {
            message.setContent(m); // 发送消息
        }
        message.setContent("EOF"); // 发送结束标志
    }
}

class Receiver implements Runnable {
    private Message message;

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

    @Override
    public void run() {
        String content;
        while (!(content = message.getContent()).equals("EOF")) { // 接收消息,直到收到结束标志
            System.out.println("Received: " + content);
        }
    }
}

在上面的例子中,我们创建了一个Message类来作为共享对象,它有两个方法getContent()和setContent()来获取和设置消息的内容。

在getContent()方法中,我们使用while循环来判断内容是否为空。如果内容为空,则调用wait()函数使当前线程进入等待状态,直到其他线程调用notify()或notifyAll()方法将其唤醒。当线程被唤醒后,它将判断内容是否为空,如果为空则继续等待,否则返回内容并设置内容为空。

在setContent()方法中,我们使用while循环来判断内容是否不为空。如果内容不为空,则调用wait()函数使当前线程进入等待状态,直到其他线程调用notify()或notifyAll()方法将其唤醒。当线程被唤醒后,它将设置内容并将内容设置为不为空。

在main函数中,我们创建了一个发送线程和一个接收线程。发送线程通过调用message.setContent()方法来发送消息,接收线程通过调用message.getContent()方法来接收消息。当发送线程发送结束标志时,接收线程将停止接收。

通过使用wait()函数和notify()函数,我们可以实现线程的等待和唤醒。在上面的例子中,当内容为空时,接收线程将进入等待状态,直到发送线程设置内容,并调用notifyAll()函数将其唤醒。当内容不为空时,发送线程将进入等待状态,直到接收线程读取内容,并调用notifyAll()函数将其唤醒。这样可以保证发送线程和接收线程之间的同步。

总的来说,使用wait()函数可以实现线程的等待和唤醒,从而协调多个线程的执行顺序和数据传递。但使用时需要注意上述条件以及异常的处理。