分享
 
 
 

Java Thread Programming 1.8.2 - Inter-thread Communication

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

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() - begin

threadB - begin synchronized notify ...

threadB - end synchronized notify ...

threadB - in notifyProceed() - end

threadA - in waitProceed() - begin

threadA - 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() - begin

threadB - begin synchronized notify ...

threadB - end synchronized notify ...

threadB - in notifyProceed() - end

threadA - in waitProceed() - begin

threadA - in waitProceed() - end

main - 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 ... begin

threadB - entering removeItem()...

threadB - list wait ... begin

threadC - entering addItem() ...

threadC - list notify ... begin

threadC - list notify ... end

threadA - list wait ... end

threadA - leaveing removeItem() ...

threadA - in run() remove item you remove hello

threadB - list wait ... end

threadC - 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 ... begin

threadB - entering removeItem()...

threadB - list wait ... begin

threadC - entering addItem() ...

threadC - list notify ... begin

threadC - list notify ... end

threadA - list wait ... end

threadA - leaveing removeItem() ...

threadA - in run() remove item you remove hello

threadB - list wait ... end

threadB - list wait ... begin

threadC - leave addItem() ...

threadB - interrupted

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有