Missed Notification A missed notification occurs when threadB tries to notify threadA, but threadA is not yet waiting for the notification. In a multithreaded environment like Java, you don’t have much control over which thread runs and for how long. This uncertainty can lead to a situation in which most of the time an application is run, threadA is waiting before threadB does the notification. But occasionally, threadB does the notification before threadA is waiting. This missed notification scenario can be quite dangerous. Missed Notification指:线程B试图通知线程A,但线程A并没有在等待通知。这并不是不可能出现的。在多线程环境中,我们不能控制哪个线程执行,执行多长时间,这种不确定有可能导致在一个线程等待之前就先行通知,这是一种很危险的情况。如下程序会出现这种情况: /* * Created on 2005-7-14 * * Java Thread Programming - Paul Hyde * Copyright ? 1999 Sams Publishing * Jonathan Q. Bo 学习笔记 * */package org.tju.msnrl.jonathan.thread.chapter8; /** * @author Jonathan Q. Bo from TJU MSNRL * * Email:jonathan.q.bo@gmail.com * Blog:blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun * * Enjoy Life with Sun! * */public class MissedNotify { private Object proceedLock; public MissedNotify(){ proceedLock = new Object(); } public void waitProceed() throws InterruptedException{ print("in waitProceed() - begin"); synchronized(proceedLock){ print("begin synchronized wait ..."); proceedLock.wait(); print("end synchronized wait ..."); } print("in waitProceed() - end"); } public void notifyProceed(){ print("in notifyProceed() - begin"); synchronized(proceedLock){ print("begin synchronized notify ..."); proceedLock.notifyAll(); print("end synchronized notify ..."); } print("in notifyProceed() - end"); } public static void print(String msg){ String temp = Thread.currentThread().getName(); System.out.println(temp + " - " + msg); } public static void main(String[] args) { final MissedNotify mn = new MissedNotify(); Runnable runA = new Runnable(){ public void run(){ try{ Thread.sleep(1000);//wait()后执行 mn.waitProceed(); }catch(InterruptedException e){ e.printStackTrace(); } } }; Thread threadA= new Thread(runA,"threadA"); threadA.start(); Runnable runB = new Runnable(){ public void run(){ try{ Thread.sleep(500);//notify()先执行 mn.notifyProceed(); }catch(InterruptedException e){ e.printStackTrace(); } } }; Thread threadB = new Thread(runB,"threadB"); threadB.start(); try{ Thread.sleep(10000); }catch(InterruptedException e){ } print("interrupt thread A ..."); threadA.interrupt(); }} 输出结果:threadB - in notifyProceed() - beginthreadB - begin synchronized notify ...threadB - end synchronized notify ...threadB - in notifyProceed() - endthreadA - in waitProceed() - beginthreadA - begin synchronized wait ...main - interrupt thread A ...java.lang.InterruptedException at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:429) at org.tju.msnrl.jonathan.thread.chapter8.MissedNotify.waitProceed(MissedNotify.java:35) at org.tju.msnrl.jonathan.thread.chapter8.MissedNotify$1.run(MissedNotify.java:66) at java.lang.Thread.run(Thread.java:534) 解决方法:只需加一个标志位: /* * Created on 2005-7-14 * * Java Thread Programming - Paul Hyde * Copyright ? 1999 Sams Publishing * Jonathan Q. Bo 学习笔记 * */package org.tju.msnrl.jonathan.thread.chapter8; /** * @author Jonathan Q. Bo from TJU MSNRL * * Email:jonathan.q.bo@gmail.com * Blog:blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun * * Enjoy Life with Sun! * */public class MissedNotifyFix { private Object proceedLock; private boolean okToProceed; public MissedNotifyFix(){ okToProceed = false; proceedLock = new Object(); } public void waitProceed() throws InterruptedException{ print("in waitProceed() - begin"); synchronized(proceedLock){ while(!okToProceed){ print("begin synchronized wait ..."); proceedLock.wait(); print("end synchronized wait ..."); } } print("in waitProceed() - end"); } public void notifyProceed(){ print("in notifyProceed() - begin"); synchronized(proceedLock){ okToProceed = true; print("begin synchronized notify ..."); proceedLock.notifyAll(); print("end synchronized notify ..."); } print("in notifyProceed() - end"); } public static void print(String msg){ String temp = Thread.currentThread().getName(); System.out.println(temp + " - " + msg); } public static void main(String[] args) { final MissedNotifyFix mn = new MissedNotifyFix(); Runnable runA = new Runnable(){ public void run(){ try{ Thread.sleep(1000); mn.waitProceed(); }catch(InterruptedException e){ e.printStackTrace(); } } }; Thread threadA= new Thread(runA,"threadA"); threadA.start(); Runnable runB = new Runnable(){ public void run(){ try{ Thread.sleep(500); mn.notifyProceed(); }catch(InterruptedException e){ e.printStackTrace(); } } }; Thread threadB = new Thread(runB,"threadB"); threadB.start(); try{ Thread.sleep(10000); }catch(InterruptedException e){ } print("interrupt thread A ..."); threadA.interrupt(); }} 输出结果:threadB - in notifyProceed() - beginthreadB - begin synchronized notify ...threadB - end synchronized notify ...threadB - in notifyProceed() - endthreadA - in waitProceed() - beginthreadA - in waitProceed() - endmain - interrupt thread A ... Early Notification If a thread is notified while waiting, but the condition the thread is waiting for has not yet been met, the thread has received an early notification. An early notification can also occur if the condition is briefly met but quickly changes so it’s no longer met. This might sound strange, but early notification can happen due to subtle errors in the code (generally when an if is used instead of a while). Early notification是指:当一个等待线程被通知的时候,它等待的条件不再满足,这时我们说,线程收到了一个early notification。Early notification在等待的条件瞬间满足然后立刻改变不再满足时,也会发生。通常在一个需要使用while的地方使用了if。 Early notification的代码:/* * Created on 2005-7-14 * * Java Thread Programming - Paul Hyde * Copyright ? 1999 Sams Publishing * Jonathan Q. Bo 学习笔记 * */package org.tju.msnrl.jonathan.thread.chapter8; import java.util.*; /** * @author Jonathan Q. Bo from TJU MSNRL * * Email:jonathan.q.bo@gmail.com * Blog:blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun * * Enjoy Life with Sun! * */public class EarlyNotify { private List list; public EarlyNotify(){ list = Collections.synchronizedList(new LinkedList()); } public String removeItem() throws InterruptedException{ print("entering removeItem()..."); synchronized(list){ if(list.isEmpty()){ print("list wait ... begin"); list.wait(); print("list wait ... end"); } String item = (String)list.remove(0); print("leaveing removeItem() ..."); return "you remove " + item; } } public void addItem(String item){ print("entering addItem() ..."); synchronized(list){ list.add(item); print("list notify ... begin"); list.notifyAll(); print("list notify ... end"); } print("leave addItem() ..."); } public static void print(String msg){ String temp = Thread.currentThread().getName(); System.out.println(temp + " - " + msg); } public static void main(String[] args) { final EarlyNotify en = new EarlyNotify(); Runnable runA = new Runnable(){ public void run(){ try{ String item = en.removeItem(); print("in run() remove item " + item); }catch(InterruptedException e1){ print("interrupted"); }catch(Exception e2){ print("exception" + e2.getMessage()); } } }; Runnable runB = new Runnable(){ public void run(){ en.addItem("hello"); } }; try{ Thread threadA = new Thread(runA,"threadA"); threadA.start(); Thread.sleep(500); Thread threadB = new Thread(runA,"threadB"); threadB.start(); Thread.sleep(500); Thread threadC = new Thread(runB,"threadC"); threadC.start(); Thread.sleep(10000); threadA.interrupt(); threadB.interrupt(); }catch(InterruptedException e1){ }catch(Exception e2){ } }} 输出结果:threadA - entering removeItem()...threadA - list wait ... beginthreadB - entering removeItem()...threadB - list wait ... beginthreadC - entering addItem() ...threadC - list notify ... beginthreadC - list notify ... endthreadA - list wait ... endthreadA - leaveing removeItem() ...threadA - in run() remove item you remove hellothreadB - list wait ... endthreadC - leave addItem() ...threadB - exceptionIndex: 0, Size: 0 正确的代码:/* * Created on 2005-7-14 * * Java Thread Programming - Paul Hyde * Copyright ? 1999 Sams Publishing * Jonathan Q. Bo 学习笔记 * */package org.tju.msnrl.jonathan.thread.chapter8; import java.util.*; /** * @author Jonathan Q. Bo from TJU MSNRL * * Email:jonathan.q.bo@gmail.com * Blog:blog.csdn.net/jonathan_q_bo * blog.yesky.net/jonathanundersun * * Enjoy Life with Sun! * */public class EarlyNotifyFix { private List list; public EarlyNotifyFix(){ list = Collections.synchronizedList(new LinkedList()); } public String removeItem() throws InterruptedException{ print("entering removeItem()..."); synchronized(list){ while(list.isEmpty()){//use while instead of if print("list wait ... begin"); list.wait(); print("list wait ... end"); } String item = (String)list.remove(0); print("leaveing removeItem() ..."); return "you remove " + item; } } public void addItem(String item){ print("entering addItem() ..."); synchronized(list){ list.add(item); print("list notify ... begin"); list.notifyAll(); print("list notify ... end"); } print("leave addItem() ..."); } public static void print(String msg){ String temp = Thread.currentThread().getName(); System.out.println(temp + " - " + msg); } public static void main(String[] args) { final EarlyNotifyFix en = new EarlyNotifyFix(); Runnable runA = new Runnable(){ public void run(){ try{ String item = en.removeItem(); print("in run() remove item " + item); }catch(InterruptedException e1){ print("interrupted"); }catch(Exception e2){ print("exception" + e2.getMessage()); } } }; Runnable runB = new Runnable(){ public void run(){ en.addItem("hello"); } }; try{ Thread threadA = new Thread(runA,"threadA"); threadA.start(); Thread.sleep(500); Thread threadB = new Thread(runA,"threadB"); threadB.start(); Thread.sleep(500); Thread threadC = new Thread(runB,"threadC"); threadC.start(); Thread.sleep(10000); threadA.interrupt(); threadB.interrupt(); }catch(InterruptedException e1){ }catch(Exception e2){ } }} 输出结果:threadA - entering removeItem()...threadA - list wait ... beginthreadB - entering removeItem()...threadB - list wait ... beginthreadC - entering addItem() ...threadC - list notify ... beginthreadC - list notify ... endthreadA - list wait ... endthreadA - leaveing removeItem() ...threadA - in run() remove item you remove hellothreadB - list wait ... endthreadB - list wait ... beginthreadC - leave addItem() ...threadB - interrupted
Java Thread Programming 1.8.2 - Inter-thread Communication
时间: 2024-11-01 15:14:57
Java Thread Programming 1.8.2 - Inter-thread Communication的相关文章
Java Thread Programming 1.8.3 - Inter-thread Communication
CubbyHole Example The class CubbyHole (see Listing 8.9) simulates a cubbyhole. A cubbyhole is a slot that can have only one item in it at a time. One thread puts an item into the slot and another thread takes it out. If a thread tries to put an item
Java Thread Programming 1.8.4 - Inter-thread Communication
Streaming Data Between Threads Using Pipes The java.io package provides many classes for writing and reading data to and from streams. Most of the time, the data is written to or read from a file or network connection. Instead of streaming data to a
Java Thread Programming 1.8.2 - Inter-thread Commu
Missed NotificationA missed notification occurs when threadB tries to notify threadA, but threadA is not yet waiting for the notification. In a multithreaded environment like Java, you don't have much control over which thread runs and for how long.
Java Thread Programming 1.8.3 - Inter-thread Commu
CubbyHole ExampleThe class CubbyHole (see Listing 8.9) simulates a cubbyhole. A cubbyhole is a slot that can have only one item in it at a time. One thread puts an item into the slot and another thread takes it out. If a thread tries to put an item i
Java Thread Programming 1.7 - Concurrent Access to Objects and Variables
access|object When multiple threads are interacting with an object, controls need to be in place to ensure that the threads don't adversely affect one another. This chapter deals with issues that can introduce subtle errors in your application. An ap
Java Thread Programming 1.8.1 - Inter-thread Communication
The Need for Inter-thread Signaling Through synchronization, one thread can safely change values that another thread will read. How does the second thread know that the values have changed? What if the second thread is waiting for the values to chang
Java多线程:“基础篇”03之Thread中start()和run()的区别
概要 Thread类包含start()和run()方法,它们的区别是什么?本章将对此作出解答.本章内容包括: start() 和 run()的区别说明 start() 和 run()的区别示例 start() 和 run()相关源码(基于 JDK1.7.0_40) 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3479083.html start() 和 run()的区别说明 start() : 它的作用是启动一个新线程,新线程会执行相应的run()
JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口
JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一.Thread 如何在自定义的代码中,自定义一个线程呢? 我们查看API文档,我们要启动一个线程,先实现一个子类, package com.lgl.hellojava; public class MyThread extends Thread { @Override public void run()
Java Network Programming 笔记(1)
笔记 Java Network Programming 笔记 n5 一 网络基本概念Chapter2 Basic Network Concepts 2.1 Networkskeywords: network, node, host, address, name, packet-switched, protocol 网络是可以或多或少实时地相互发送和接收数据的计算机和其他设备的集合. 网络上的每台机器被称作结点(node),大多数结点是计算机,但是打印机,路由器,桥,网关,哑终端和可口可乐机都