關于使用Thread.yield()進行線程通訊的問題
//代碼1 package?communication; import?java.util.Random; public?class?Flag?{ public?static?void?main(String[]?args)?{ FlagSender?f?=?new?FlagSender(); FlagRec?r?=?new?FlagRec(f); Thread?t1?=?new?Thread(f); Thread?t2?=?new?Thread(r); t1.start(); t2.start(); } } class?FlagSender?implements?Runnable{ private?int?theValue; private?boolean?flag; public?int?getTheValue()?{ return?theValue; } public?void?setTheValue(int?theValue)?{ this.theValue?=?theValue; } public?boolean?isFlag()?{ return?flag; } public?void?setFlag(boolean?flag)?{ this.flag?=?flag; } @Override public?void?run()?{ for?(int?i?=?0;?i?<?5;?i++)?{ while(flag){ Thread.yield(); } theValue?=?new?Random().nextInt(1000); System.out.println("send?the?value?is?"+theValue); flag?=?true; } } } class?FlagRec?implements?Runnable{ private?FlagSender?f;? public?FlagRec(FlagSender?f)?{ super(); this.f?=?f; } @Override public?void?run()?{ for?(int?i?=?0;?i?<?5;?i++)?{ while(!f.isFlag()){ Thread.yield(); } System.out.println("receive?the?value?is?"+f.getTheValue()); f.setFlag(false); } } }
//代碼2 package?communication; import?java.util.Random; public?class?WrongOfFlag?{ public?static?void?main(String[]?args)?{ FlagSender1?f?=?new?FlagSender1(); FlagRec1?r?=?new?FlagRec1(); Thread?t1?=?new?Thread(f); Thread?t2?=?new?Thread(r); t1.start(); t2.start(); } } class?FlagSender1?implements?Runnable{ private?int?theValue; private?boolean?flag; public?int?getTheValue()?{ return?theValue; } public?void?setTheValue(int?theValue)?{ this.theValue?=?theValue; } public?boolean?isFlag()?{ return?flag; } public?void?setFlag(boolean?flag)?{ this.flag?=?flag; } @Override public?void?run()?{ for?(int?i?=?0;?i?<?5;?i++)?{ while(flag){ Thread.yield(); } theValue?=?new?Random().nextInt(1000); System.out.println("send?the?value?is?"+theValue); flag?=?true; } } } class?FlagRec1?implements?Runnable{ FlagSender?f?=?new?FlagSender(); @Override public?void?run()?{ for?(int?i?=?0;?i?<?5;?i++)?{ while(!f.isFlag()){ Thread.yield(); } System.out.println("receive?the?value?is?"+f.getTheValue()); f.setFlag(false); } } }
為什么要讓FlagSender作為FlagRec的成員,像代碼二中直接new了FlagSender為什么結果只輸出一個send the value is 138,然后就死循環空程序了,結果如下圖
2017-02-06
代碼1:兩個線程同時走,他倆公用一個FlagSender對象里面的flag,當線程t1走第一遍時,flag等于false,不等待直接輸出,然后將falg致成true,線程t1等待,這時候線程t2 while里面的!f.isFlag() 為false,所以往下進行輸出又將flag致成false,這時線程t1又開始執行。以此類推。
代碼2:兩個對象都在while里面進行死循環,所以只打印一次。