Core Java Tutorial -- Thread wait, notify and notifyAll 2022-05-28 14:17 45阅读 0赞 Java 中的 Object 类包含三个最终方法,它们允许线程就资源的锁定状态进行通信。这些方法是 wait()、notify() 和 notifyAll() 。所以今天我们将探究 Java 程序中 wait,notify 和 notifyAll。 1. wait, notify and notifyAll in Java 1. wait 2. notify 3. notifyAll 4. Message 5. Waiter 6. Notifier 7. WaitNotifyTest # wait, notify and notifyAll in Java # 在任何对象上调用这些方法的当前线程应具有对象监视器,否则会抛出 `java.lang.IllegalMonitorStateException` 异常。 ## wait ## Object wait 方法由三种,一个无限期等待任何其他线程调用 Object notify 或 notifyAll 方法来唤醒当前线程。其他两种方法会让当前线程在唤醒之前等待特定时间。 ## notify ## notify 方法只唤醒等待对象的一个线程,并且该线程开始执行。所以如果有多个线程在等待一个对象,这个方法只会唤醒其中一个。要唤醒的线程的选择取决于线程管理的操作系统实现。 ## notifyAll ## notifyAll 方法唤醒等待对象的所有线程,但哪一个将首先处理取决于操作系统的实现。 这些方法可用于实现[生产者消费者问题][Link 1],其中消费者线程正在等待队列中的对象,生产者线程将对象放入队列并通知等待的线程。 让我们看看一个例子,其中多个线程在同一个对象上工作,我们使用wait,notify 和 notifyAll 方法。 ## Message ## 线程可以工作并调用 wait 和 notify 方法的 Java bean 类。 package Thread; public class Message { private String msg; public Message(String str) { this.msg = str; } public String getMsg() { return msg; } public void setMsg(String str) { this.msg = str; } } ## Waiter ## 一个将等待其他线程调用通知方法来完成处理的类。请注意 Waiter 线程使用synchronized block(同步块)在 Message 对象上拥有监视器。 package Thread; public class Waiter implements Runnable { private Message msg; public Waiter(Message m) { this.msg = m; } @Override public void run() { String name = Thread.currentThread().getName(); synchronized (msg) { try { System.out.println(name + " waiting to get notified at time:" + System.currentTimeMillis()); msg.wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + " waiter thread got notified at time:" + System.currentTimeMillis()); //process the message now System.out.println(name + " processed: " + msg.getMsg()); } } } ## Notifier ## 一个将在 Message 对象上处理的类,然后调用notify方法来唤醒等待Message 对象的线程。请注意,synchronized block(同步块)用于拥有 Message 对象的监视器。 package Thread; public class Notifier implements Runnable { private Message msg; public Notifier(Message msg) { this.msg = msg; } @Override public void run() { String name = Thread.currentThread().getName(); System.out.println(name + " started"); try { Thread.sleep(1000); synchronized (msg) { msg.setMsg(name + " Notifier work done"); msg.notify(); // msg.notifyAll(); } } catch (InterruptedException e) { e.printStackTrace(); } } } ## WaitNotifyTest ## 测试类将创建 Waiter 和 Notifier 的多个线程并启动它们。 package Thread; public class WaitNotifyTest { public static void main(String[] args) { Message msg = new Message("process it"); Waiter waiter = new Waiter(msg); new Thread(waiter, "waiter").start(); Waiter waiter1 = new Waiter(msg); new Thread(waiter1, "waiter1").start(); Notifier notifier = new Notifier(msg); new Thread(notifier, "notifier").start(); System.out.println("All the threads are started"); } } 当我们调用上述程序时,我们会看到下面的输出,但程序不会完成,因为有两个线程在等待 Message 对象,而 notify() 方法只唤醒其中的一个,另一个线程仍在等待通知。 All the threads are started waiter waiting to get notified at time:1522409220246 waiter1 waiting to get notified at time:1522409220246 notifier started waiter waiter thread got notified at time:1522409221247 waiter processed: notifier Notifier work done If we comment the notify() call and uncomment the notifyAll() call in Notifier class, below will be the output produced. 如果我们在 Notifier 类中注释掉 notify() 调用并取消注释 notifyAll() 调用,则下面将生成输出。 All the threads are started waiter waiting to get notified at time:1522411583100 waiter1 waiting to get notified at time:1522411583109 notifier started waiter waiter thread got notified at time:1522411584111 waiter processed: notifier Notifier work done waiter1 waiter thread got notified at time:1522411584111 waiter1 processed: notifier Notifier work done 由于 notifyAll() 方法唤醒 Waiter 线程和程序完成,并在执行后终止。 [Link 1]: https://www.journaldev.com/1034/java-blockingqueue-example 文章版权声明:注明蒲公英云原创文章,转载或复制请以超链接形式并注明出处。
相关 Core Java Tutorial -- Threads in Java Process(进程)和 Thread(线程)是执行的两个基本单元。并发编程更关心 Java 线程 0.1 Process 0.2 Thread 1 Java Thr 叁歲伎倆/ 2022年05月28日 11:49/ 0 赞/ 31 阅读
相关 Core Java Tutorial -- Thread.sleep() 1. Thread.sleep in Java 1. Java Thread Sleep Example 2. Java Thre 待我称王封你为后i/ 2022年05月28日 13:09/ 0 赞/ 48 阅读
相关 Core Java Tutorial -- Thread Join Java Thread join 方法可用于暂停当前线程执行,直到指定线程死亡。有三个重载 join 函数。 Java Thread join `public f 旧城等待,/ 2022年05月28日 14:14/ 0 赞/ 9 阅读
相关 Core Java Tutorial -- Thread wait, notify and notifyAll Java 中的 Object 类包含三个最终方法,它们允许线程就资源的锁定状态进行通信。这些方法是 wait()、notify() 和 notifyAll() 。所以今天我们将 我不是女神ヾ/ 2022年05月28日 14:17/ 0 赞/ 46 阅读
相关 Core Java Tutorial -- Daemon Thread Java 中的守护线程可以用于在后台运行一些任务。当我们在 Java 中创建一个线程时,默认情况下它是一个用户线程,如果它正在运行,JVM 将不会终止程序。 Daemon 冷不防/ 2022年05月28日 15:20/ 0 赞/ 29 阅读
相关 Core Java Tutorial -- Thread Local Java ThreadLocal 被用于创建线程局部变量。我们知道一个对象的所有线程共享它的变量,所以这个变量不是线程安全的。我们可以为线程安全使用同步,但如果我们像避免同步, ╰半橙微兮°/ 2022年05月28日 15:20/ 0 赞/ 37 阅读
相关 Core Java Tutorial -- Timer Thread Java `java.util.Timer` 是一个使用程序类,可用于安排将来某个时间执行的线程。Java Timer 类可用于安排一次于运行的任务或定期运行的任务。 Ja ╰+攻爆jí腚メ/ 2022年05月28日 15:20/ 0 赞/ 44 阅读
相关 wait,notify,notifyAll用法解析 在并发开发中,锁是非常常见的,而wait/notify也经常会和锁一起使用,例如在生产者消费者模式中。而且wait/notify也必须和锁一起使用,因为它们都是基于对象的,否则 青旅半醒/ 2022年06月11日 11:37/ 0 赞/ 48 阅读
相关 wait、notify、notifyAll和Condition from:http://www.cnblogs.com/dolphin0520/p/3920385.html Java并发编程:线程间协作的两种方式:wait、no ╰半夏微凉°/ 2022年09月24日 19:26/ 0 赞/ 48 阅读
相关 Java中的wait,notify和notifyAll 资源锁 在Java中,如果一个资源被上了锁,则其他线程必须要等待该资源被释放后才能使用。如下: String student = "test"; Run £神魔★判官ぃ/ 2022年11月05日 08:56/ 0 赞/ 43 阅读
还没有评论,来说两句吧...