Java中wait()方法和notify()/notifyAll()

简介: Java中wait()方法和notify()/notifyAll()

Java中wait()方法和notify()/notifyAll()

在Java中,wait()、notify()和notifyAll()是用于实现线程间的协作和通信的方法,它们都是定义在Object类中的。

  • wait()方法:wait()方法用于使当前线程进入等待状态,并释放当前对象的锁。调用wait()方法后,当前线程将被挂起,直到其他线程调用相同对象上的notify()或notifyAll()方法来唤醒该线程。在等待期间,线程会释放对对象的锁,让其他线程有机会获取锁并执行操作。

  • notify()方法:notify()方法用于唤醒在相同对象上调用wait()方法而进入等待状态的一个线程。如果有多个线程在等待,只能唤醒其中一个线程,具体唤醒哪个线程是不确定的,取决于线程调度器的选择。

  • notifyAll()方法:notifyAll()方法用于唤醒在相同对象上调用wait()方法而进入等待状态的所有线程。当调用notifyAll()方法后,所有等待线程将被唤醒,但只有一个线程能获取锁并继续执行。

这些方法通常与synchronized关键字一起使用,以实现线程之间的协作和同步。以下是它们的一些使用场景和优势:

使用场景:

  • 多线程协作:当线程之间需要进行协作,例如等待某个条件满足后再继续执行,或者在特定条件下唤醒其他线程时,可以使用wait()、notify()和notifyAll()方法。
  • 生产者消费者模型:在生产者消费者模型中,生产者线程通过wait()方法等待缓冲区不满,消费者线程通过wait()方法等待缓冲区不空,而生产者线程或消费者线程通过notify()或notifyAll()方法唤醒对方继续执行。

优势:

  • 线程通信:wait()、notify()和notifyAll()提供了一种简单而有效的线程通信机制,允许线程之间进行等待和唤醒操作,实现了线程的协同工作。
  • 避免忙等待:通过使用wait()方法,线程可以释放锁并进入等待状态,避免了忙等待的情况,节省了CPU资源。

以下是一个简单示例,展示了如何使用wait()和notify()方法实现两个线程的协作:

public class WaitNotifyExample {
    public static void main(String[] args) {
        final Object lock = new Object();

        Thread threadA = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Thread A is waiting...");
                    lock.wait(); // 线程A等待,释放锁
                    System.out.println("Thread A is resumed.");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread threadB = new Thread(() -> {
            synchronized (lock) {
                System.out.println("Thread B is performing some task.");
                System.out.println("Thread B is notifying...");
                lock.notify(); // 唤醒等待的线程A
            }
        });

        threadA.start();
        threadB.start();
    }
}

在上述示例中,线程A先获取锁并进入同步块,然后调用wait()方法进入等待状态,释放了锁。线程B获取锁后执行一些任务,然后调用notify()方法唤醒等待的线程A,线程A被唤醒后继续执行。这样实现了线程A和线程B的协作和通信。

相关文章
|
7天前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
12天前
|
Java
用JAVA架建List集合为树形结构的代码方法
这段代码定义了一个表示树形结构的 `Node` 类和一个用于构建树形结构的 `TreeController`。`Node` 类包含基本属性如 `id`、`pid`、`name` 和 `type`,以及子节点列表 `children`。`TreeController` 包含初始化节点列表并将其转换为树形结构的方法。通过过滤和分组操作实现树形结构的构建。详情可见:[代码示例链接1](http://www.zidongmutanji.com/zsjx/43551.html),[代码效果参考链接2](https://www.257342.com/sitemap/post.html)。
25 5
|
15天前
|
安全 Java 开发者
【技术咖必看】Java异常处理新境界:throws关键字,打造万无一失的方法签名!
【技术咖必看】Java异常处理新境界:throws关键字,打造万无一失的方法签名!
29 3
|
15天前
|
安全 Java 程序员
【程序猿逆袭指南】Java高手的秘密武器:throws关键字,让你的方法签名霸气侧漏!
【程序猿逆袭指南】Java高手的秘密武器:throws关键字,让你的方法签名霸气侧漏!
12 3
|
16天前
|
Java Spring 容器
Java获取接口的所有实现类方法
这篇文章介绍了在Java中获取接口所有实现类的方法,包括使用JDK的ServiceLoader(SPI机制)和Spring Boot中的@Autowired自动注入及ApplicationContextAware接口两种方式。
37 1
|
17天前
|
监控 Java API
提升 Java 后台性能的十大方法
提升 Java 后台性能的十大方法
29 2
|
20天前
|
Java
|
20天前
|
安全 Java 测试技术
Java 中的阻塞方法
【8月更文挑战第22天】
21 4
|
20天前
|
Java
|
20天前
|
Java
Java 中 notify() 和 notifyAll() 的区别
【8月更文挑战第22天】
41 4