等待唤醒机制

简介: 等待唤醒机制

等待唤醒机制(Wait-Notify)是一种线程间协作的机制,用于实现线程之间的通信和同步。它主要涉及两个操作:等待(wait)和唤醒(notify)。

等待唤醒机制通常应用于多线程环境下,其中一个线程等待某个条件得到满足,而另一个线程负责在满足条件时通知等待的线程继续执行。

具体来说,当一个线程调用对象的wait()方法时,它会释放当前持有的锁,并且进入等待状态,直到其他线程通过notify()或notifyAll()方法来唤醒它。被唤醒的线程将重新尝试获取锁,然后继续执行。

而唤醒线程通常在满足某个条件时,通过调用对象的notify()或notifyAll()方法来通知正在等待的线程继续执行。notify()方法会随机选择一个等待线程进行唤醒,而notifyAll()方法会唤醒所有等待的线程,使它们进入就绪状态,等待获取锁以继续执行。

等待唤醒机制提供了一种有效的线程间协作方式,使得线程可以根据特定条件进行等待和唤醒,从而实现对共享资源的更好利用和管理。

需要注意的是,等待唤醒机制必须在同步代码块中使用,即对共享对象进行操作,以确保正确的并发控制和线程间的协作。在调用wait()、notify()或notifyAll()方法之前,线程必须先获得相应对象的锁,否则会抛出IllegalMonitorStateException异常。

下面是一个简单的Java代码示例,演示了等待唤醒机制的实现:

public class WaitNotifyExample {
    public static void main(String[] args) {
        Message message = new Message();
        Thread producerThread = new Thread(new Producer(message));
        Thread consumerThread = new Thread(new Consumer(message));
        producerThread.start();
        consumerThread.start();
    }
}
class Message {
    private String content;
    private boolean isProduced;
    public synchronized void produce(String content) {
        while (isProduced) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.content = content;
        System.out.println("Produced: " + content);
        isProduced = true;
        notify();
    }
    public synchronized String consume() {
        while (!isProduced) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        String consumedContent = content;
        System.out.println("Consumed: " + consumedContent);
        isProduced = false;
        notify();
        return consumedContent;
    }
}
class Producer implements Runnable {
    private Message message;
    public Producer(Message message) {
        this.message = message;
    }
    @Override
    public void run() {
        String[] contents = {"Message 1", "Message 2", "Message 3"};
        for (String content : contents) {
            message.produce(content);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Consumer implements Runnable {
    private Message message;
    public Consumer(Message message) {
        this.message = message;
    }
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            String consumedContent = message.consume();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

下面我们逐步解释代码的细节:

  1. 首先,我们创建了一个Message类,用于消息传递。该类包含了一个消息内容content和一个表示是否已经生产消息的标志isProduced
  2. Message类中的produce()方法用于生产消息。在该方法中,使用synchronized关键字确保多个线程在访问produce()方法时的互斥性。
  3. produce()方法中,使用while循环来检查是否已经生产消息。如果isProducedtrue,说明已经生产了消息,则调用wait()方法让当前线程进入等待状态,直到被其他线程调用notify()方法唤醒。
  4. 当前线程被唤醒后,会继续执行后续代码,将传入的消息内容赋值给content变量,并将isProduced标志设置为true,表示消息已经生产。然后通过notify()方法唤醒在等待的其他线程。
  5. Message类中的consume()方法用于消费消息。同样,使用synchronized关键字确保多个线程在访问consume()方法时的互斥性。
  6. consume()方法中,同样使用while循环来检查是否已经生产消息。如果isProducedfalse,说明还没有生产消息,则调用wait()方法让当前线程进入等待状态,直到被其他线程调用notify()方法唤醒。
  7. 当前线程被唤醒后,会继续执行后续代码,将content变量的值作为消费的消息内容,并将isProduced标志设置为false,表示消息已经被消费。然后通过notify()方法唤醒在等待的其他线程。
  8. 在主程序中,我们创建了一个Message对象和两个线程:生产者线程Producer和消费者线程Consumer
  9. 生产者线程通过调用message.produce(content)方法来生产消息。在示例中,我们定义了3个消息内容,分别进行生产,并且每次生产完后等待1秒钟。
  10. 消费者线程通过调用message.consume()方法来消费消息。在示例中,我们简单地循环3次消费消息,并且每次消费后等待1秒钟。

通过以上操作,生产者和消费者线程之间进行消息的生产和消费,并且使用了等待唤醒机制进行线程间的通信和同步。当消息已经生产时,生产者线程进入等待状态,等待消费者线程消费完毕后唤醒;当消息还没有被生产时,消费者线程进入等待状态,等待生产者线程生产完毕后唤醒。

需要注意的是,为了保证正确的并发控制和线程间的协作,必须在调用wait()notify()notifyAll()方法之前先获取锁(即使用synchronized关键字修饰的方法或代码块),否则会抛出IllegalMonitorStateException异常。


相关文章
|
9月前
|
Java
JUC并发编程之等待唤醒机制
在JUC(Java Util Concurrent)并发编程中,线程等待唤醒机制是实现线程之间协作和同步的重要手段。这种机制允许一个线程挂起等待某个条件满足后被唤醒,以及另一个线程在满足某个条件后唤醒等待的线程。在Java中,有多种实现线程等待唤醒机制的方式,包括使用Object的wait()和notify()方法、Condition接口以及LockSupport类。
|
5月前
|
安全 调度
等待唤醒机制
线程间的`wait`、`notify`及`notifyAll`方法用于同步控制。`wait`使线程释放锁并进入等待状态,直至被`notify`或`notifyAll`唤醒。`notify`随机唤醒一个等待线程,而`notifyAll`唤醒所有等待线程。这些方法需在`synchronized`块内使用,以保证线程安全。正确使用这些方法可避免线程饿死现象,确保线程间有效协作。
78 7
等待唤醒机制
|
7月前
多线程卖票问题
多线程卖票问题
|
7月前
|
消息中间件 Python
线程通信
【7月更文挑战第1天】
43 2
|
9月前
线程间的通信
线程间的通信
47 0
|
9月前
|
Java
并发编程-线程等待唤醒机制
并发编程-线程等待唤醒机制
|
监控
线程通信
线程通信
67 0
可重入,可打断,公平锁,条件变量原理解读
可重入,可打断,公平锁,条件变量原理解读
高并发编程-使用wait和notifyAll进行线程间的通信3_多线程下的生产者消费者模型和notifyAll
高并发编程-使用wait和notifyAll进行线程间的通信3_多线程下的生产者消费者模型和notifyAll
74 0
JUC学习(一):synchronized的介绍及使用(实现多线程卖票)
JUC学习(一):synchronized的介绍及使用(实现多线程卖票)
108 0