江明涛的博客
Java中的等待与通知
Java中的等待与通知

Java中的等待与通知

Java中的等待与通知

在Java编程中,等待与通知是一种用于线程间通信和同步的机制。它使得多个线程能够有效地协同工作,以完成复杂的任务。在本文中,我们将介绍等待与通知的原理、用法和一些实例。

等待与通知的原理

等待与通知是基于Java的内置锁(也称为监视器)提供的机制。每个对象都有一个内置锁,通过使用synchronized关键字来获取和释放锁。当一个线程执行synchronized代码块时,它会持有该对象的锁。

在等待与通知的机制下,一个线程可以通过调用对象的wait()方法进入等待状态。这将导致该线程释放锁,并且在等待队列中等待其他线程唤醒它。另一个线程可以通过调用对象的notify()或notifyAll()方法来唤醒等待的线程,并通知它可以重新竞争锁。

等待与通知的用法

等待与通知的用法一般包括三个步骤:

  1. 线程进入等待状态:线程可以通过调用对象的wait()方法来进入等待状态。在等待状态下,线程释放了锁,其他线程可以获取到锁。
  2. 线程等待被唤醒:线程在等待状态下等待其他线程唤醒它。一旦被唤醒,它将重新开始竞争锁。
  3. 线程被唤醒后继续执行:一旦线程被唤醒,它将从wait()方法返回,并继续执行后续的代码。

等待与通知的机制允许线程在某个条件满足时进入等待状态,并在条件不满足时等待其他线程的通知。这可以用于实现一些同步场景,如生产者-消费者问题等。

等待与通知的实例

下面是一个使用等待与通知机制的简单示例:

class Message {
    private String message;
    
    public synchronized void setMessage(String message) {
        while (this.message != null) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        this.message = message;
        notifyAll();
    }
    
    public synchronized String getMessage() {
        while (this.message == null) {
            try {
                wait();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        String message = this.message;
        this.message = null;
        notifyAll();
        return message;
    }
}
class Producer implements Runnable {
    private Message message;
    
    public Producer(Message message) {
        this.message = message;
    }
    
    public void run() {
        String[] messages = {"Hello", "Welcome", "Goodbye"};
        for (String message : messages) {
            this.message.setMessage(message);
            System.out.println("Sent: " + message);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        this.message.setMessage("Finished");
    }
}
class Consumer implements Runnable {
    private Message message;
    
    public Consumer(Message message) {
        this.message = message;
    }
    
    public void run() {
        String message = this.message.getMessage();
        while (!message.equals("Finished")) {
            System.out.println("Received: " + message);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            message = this.message.getMessage();
        }
    }
}
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();
    }
}

在上面的示例中,一个生产者线程向消息对象发送消息,而一个消费者线程从消息对象接收消息。生产者线程通过调用setMessage()方法发送消息,并且在消息对象不为空时等待通知。消费者线程通过调用getMessage()方法接收消息,并且在消息对象为空时等待通知。

通过以上示例,我们可以看到等待与通知的用法以及它如何协同工作。这种机制允许线程在必要时等待并在合适的时候被唤醒,从而实现线程间的通信和同步。

总结而言,等待与通知是Java中用于线程间通信和同步的一种机制。它是基于对象的内置锁和synchronized关键字提供的,通过wait()和notify()方法实现。等待与通知允许一个线程在某个条件不满足时进入等待状态,并在条件满足时被其他线程唤醒。它是实现多线程协同工作的重要机制之一。