Java中使用wait()和notify()的线程间通信 - 示例教程

201 阅读6分钟

Java中的等待和通知方法用于线程间的通信,即如果一个线程想告诉另一个线程一些事情,它就使用java.lang.Object的notify()和 notifyAll()方法。一个经典的等待和通知方法的例子是生产者-消费者设计模式,其中一个线程生产并把东西放在共享桶上,然后告诉另一个线程,在共享对象中有一个你感兴趣的项目,消费者线程比选项目并做他的工作,如果没有等待()和通知(),消费者线程需要忙着检查,即使共享对象的状态没有变化。

这给使用等待和通知机制带来了一个有趣的观点,当线程改变了共享对象的状态时,就会调用notify(),即在这种情况下,生产者将桶从空变为不空,而消费者将状态从不空变为空。

另外,等待和通知方法必须从一个同步的上下文中调用,不知道为什么要读这个链接,这是有道理的。在调用这些方法时,需要记住的另一件重要事情是,使用循环来检查条件,而不是使用if块

这对初学者来说真的很棘手,他们往往不明白其中的区别,并想知道为什么等待和通知会被调用到循环中。Joshua Bloch在他的《Effective Java》一书中有一个非常翔实的项目,我强烈建议你阅读。

而且,如果你真的想掌握Java多线程和并发,那么我还建议你 看一下Udemy上Michael Pogrebinsy的**Java多线程、并发和性能优化** 课程。这是一门成为Java多线程、并发和并行编程专家的高级课程,重点强调高性能

简而言之,一个等待中的线程可能会被唤醒,而它的等待条件不会因为假性唤醒而发生任何变化。

例如,如果一个消费者线程,因为共享队列是空的而在等待,由于虚假唤醒而被唤醒,并试图从队列中获取一些东西,而没有进一步检查队列是否是空的,那么就有可能出现意想不到的结果。下面是在Java.NET中调用wait、notify和notifyAll方法的标准习语。

如何在Java中调用等待方法?例子

synchronized (object) {

while ()

object.wait()。

... // 执行适合条件的动作

}

而这里是一个使用两个线程,生产者和消费者,在Java中调用等待和通知方法的完整例子

wait notify example in Java using inter thread communication

使用wait()和notify()方法的Java线程间通信实例

Java inter thread communication example wait notify method我们有一个共享队列和两个线程,叫做生产者 和消费者。生产者线程将数字放入共享队列,消费者线程从共享桶中消耗数字。

条件是,一旦一个项目被生产出来,消费者线程必须被通知,同样,在消费后生产者线程也需要被通知。这种线程间的通信是通过等待和通知方法实现的。记住,wait和notify方法是在对象类中定义的,它们必须在同步块中调用。

并发性。

import java.util.LinkedList;

import java.util.Queue

import org.apache.log4j.Logger;

public class InterThreadCommunicationExample {

public static void main(String args[] ) {

final QueuesharedQ =new LinkedList();

Thread producer = new Producer(sharedQ);

Thread consumer = new Consumer(sharedQ);

producer.start();

consumer.start()。

}

}

public class Producer extends Thread {

private static final Logger logger = Logger.getLogger(Producer.class);

private final QueuesharedQ;

public Producer(QueuesharedQ) {

super("Producer")。

this.sharedQ = sharedQ;

}

@Override

public void run() {

for (int i = 0; i < 4; i++) {

synchronized (sharedQ) {

//等待条件--等到队列不是空的时候

while (sharedQ.size() >= 1) {

尝试 {

logger.debug("Queue is full, waiting")。

sharedQ.wait()。

} catch (InterruptedException ex) {

ex.printStackTrace()。

}

}

logger.debug("production : " + i);

sharedQ.add(i);

sharedQ.notify();

}

}

}

}

public class Consumer extends Thread {

private static final Logger logger = Logger.getLogger(Consumer.class);

private final QueuesharedQ;

公共 Consumer(QueuesharedQ) {

super("Consumer");

this.sharedQ = sharedQ;

}

@Override

public void run() {

while(true) {

synchronized (sharedQ) {

//等待条件--等到队列不是空的时候

while (sharedQ.size() == 0) {

try {

logger.debug("Queue is empty, waiting")。

sharedQ.wait()。

} catch (InterruptedException ex) {

ex.printStackTrace()。

}

}

int number = sharedQ.poll()。

logger.debug("consumering : " + number )。

sharedQ.notify()。

//终止条件

如果(number == 3){break; }

}

}

}

}

输出。

05:41:57,244 0 [Producer] DEBUG concurrency.Producer - producing : 0

05:41:57,260 16 [Producer] DEBUG concurrency.生产者 - 队列已满,正在等待

05:41:57,260 16 [Consumer] DEBUG concurrency.Consumer - consuming : 0

05:41:57,260 16 [Consumer] DEBUG concurrency.Consumer - Queue is empty,waiting

05:41:57,260 16 [Producer] DEBUG concurrency.Producer - producing : 1

05:41:57,260 16 [Producer] DEBUG concurrency.生产者 - 队列已满,正在等待

05:41:57,260 16 [Consumer] DEBUG concurrency.消费者 - 正在消费 : 1

05:41:57,260 16 [Consumer] DEBUG concurrency.Consumer - Queue is empty, waiting

05:41:57,260 16 [Producer] DEBUG concurrency.Producer - producing : 2

05:41:57,260 16 [Producer] DEBUG concurrency.生产者 - 队列已满,正在等待

05:41:57,260 16 [Consumer] DEBUG concurrency.消费者 - 正在消费: 2

05:41:57,260 16 [Consumer] DEBUG concurrency.Consumer - Queue is empty,waiting

05:41:57,260 16 [Producer] DEBUG concurrency.Producer - producing : 3

05:41:57,276 32 [Consumer] DEBUG concurrency.消费者 - 消费 : 3

以上就是这个在Java中使用wait和notify方法进行线程间通信的简单例子的全部内容。你可以看到,生产者和消费者线程正在相互通信,并使用共享队列共享数据,生产者在有一个项目可以消费时通知消费者,而消费者线程在消费完成后告诉生产者。

这也是生产者-消费者设计模式的一个经典例子,它本质上涉及到Java线程间的通信和数据共享。

你可能喜欢的其他 Java多线程和并发性文章

  • Java开发者路线图(Roadmap)

  • 5门深入学习Java多线程的课程(课程)

  • Java中的原子、同步和易失性的区别(答案)

  • 6本Java开发人员可以阅读的并发性书籍(书籍)

  • 在Java内存模型中,之前发生了什么?(答案)

  • Java中CyclicBarrier和CountDownLatch之间的区别?(答案)

  • 掌握Java并发性的5大书籍(书籍)

  • 10个Java多线程和并发性最佳实践(文章)

  • 50+线程初学者面试问题(问题)

  • 了解Java程序中的数据和代码流(答案)

  • 实践中的Java并发仍然有效吗?(答案)

  • 成为更好的Java开发者的10个技巧(技巧)

  • 10本适合有经验的程序员的高级书籍(书籍)

  • 破解编码面试的5大技巧(文章)

  • 为有经验的程序员提供的10个高级核心Java课程(课程)

感谢你阅读这篇文章,所以。如果你喜欢这个Java多线程教程,那么请与你的朋友和同事分享它。如果您有任何问题或反馈,那么请留言。

**P. S. -**如果你正在寻找一个免费的Java多线程课程来掌握线程概念,那么我也建议你看看Udemy上的这个Java多线程免费课程。它是完全免费的,你只需要一个免费的Udemy账户来加入这个课程。