使用wait()函数实现线程的等待和唤醒实例分析
在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()函数可以实现线程的等待和唤醒,从而协调多个线程的执行顺序和数据传递。但使用时需要注意上述条件以及异常的处理。
