關于線程間的交互和共享數據通常有輪詢和通知機制。一下舉例說明:Thread1和Thread2共享一塊數據ShareData,Thread1使用數據,Thread2更新數據。當Thread1使用數據時發現數據沒有更新就可以先休眠(sleep())一段時間然后再去判斷是否更新,如此反復直到數據可用,這就是所述的輪詢機制。可以看出輪詢機制需要不斷的輪詢數據狀態,很耗費資源;當采用通知機制時過程是這樣的,Thread1發現數據不可用就在ShareData上等待(ShareData.wait()),當Thread2更新數據后就通知所有在ShareData上等待的線程(ShareData.notifyAll()),這樣Thread1受到通知繼續運行。
關于等待和休眠還有另一個區別就是當線程等待時,該線程鎖定的資源是釋放掉的,這時其它線程是可以鎖定這些資源的,當線程被喚醒或者等待時限到時線程重新獲取資源才能繼續運行;而當線程休眠時線程鎖定的資源是不被釋放的。
還有一點就是要在對象lock上等待時是必須先要獲取lock的對象鎖才能進行的,即必須要類似下面的邏輯
synchronized(lock){ lock.wait()}
以下為一個簡單的示例:
package
sinpo.usagedemo;
/**
* 該例子說明線程休眠與等待以及注意事項。
*
*
@author
徐辛波(sinpo.xu@hotmail.com)
* Oct 22, 2008
*/
public class
PendingThreadDemo
{
public
Console console =
new
Console
()
;
private
void
writeToConsole1
() {
synchronized
(
console
){
try
{
Thread.sleep
(
1
*
1000
)
;
//NOTE:sleep時并未釋放console別的線程是不能鎖定console的
//TODO do things
}
catch
(
InterruptedException e
) {
e.printStackTrace
()
;
}
}
}
private
void
writeToConsole2
() {
synchronized
(
console
){
try
{
console.wait
(
1
*
1000
)
;
//NOTE:wait時別的線程是可以鎖定console的
//TODO do things
}
catch
(
InterruptedException e
) {
e.printStackTrace
()
;
}
}
}
}
//控制臺類
class
Console
{
//TODO implements me
}
|