執行緒間的通訊 :其實就是多個執行緒操作同一資源,但是操作的動作不同。
注意:
1、多個執行緒
2、同一資源
3、操作動作不同
例如乙個場景:輸入執行緒(input) 和 輸出執行緒(output) ,輸入執行緒負責操作資源(resource),resource 有 name(string) 和 ***(string)兩個變數,輸入執行緒(input) 負責為 resource 的成員賦值,輸出執行緒 (output)列印值。
分析 : 按照正常的場景來說,輸入執行緒(input)一旦為資源(resource)賦值完成後,輸出執行緒(output) 應該列印資源(resource)的成員變數值。同一資源,可通過建構函式將資源傳入執行緒。
先看如下**:
//資源
class
resource
//輸入執行緒
class
input
implements
runnable
public
void run()
else
// 目的在於做切換,賦值不同是為了更好區分是否存在問題
x = (x+1)%2;}}
}//輸出執行緒
class
output
implements
runnable
public
void run()
}}//主函式
public
class
threadwaitandnotify
}
看下列印結果(擷取部分):
輸出執行緒:傑克...man
輸出執行緒:jack...男
輸出執行緒:傑克...男
輸出執行緒:jack...man
輸出執行緒:傑克...男
輸出執行緒:傑克...man
分析: 從列印結果上來說,沒達到我們的要求,正常來說,應該是中文對應中文,英文對應英文輸出才對 ! 那為什麼會出現如下問題呢 ?其實,原因很簡單,假設輸入執行緒 (input)第一次 賦值 name = 「jack」,*** = 「man」,此時輸入執行緒(input)繼續享有執行權,做切換賦值,當賦值到 name = 「傑克」時,即將進行*** = 「男」賦值時,失去了執行權,此時,cpu執行權被輸出執行緒(output)拿到,輸出操作資源(res)的成員變數值,由於是操作同一資源,此時資源(res)的 name = 「傑克」, *** = 「man」,將其輸出。導致了如上結果。
解決方案: 同步。那麼同步應該注意哪些地方呢 ?
( 1 ) 首先明白 執行緒 對資源的操作 ** 是哪些,這個比較好解決,就是 run方法的**。
( 2 ) 其次,鎖必須唯一。那有兩種選擇,可以是res物件,也可以是位元組碼檔案物件(在記憶體中,input.class和ouput.class也是唯一存在的)
修改**如下:
//資源
class
resource
//輸入執行緒
class
input
implements
runnable
public
void run()
else
x = (x+1)%2;}}
}}//輸出執行緒
class
output
implements
runnable
@override
public
void run() }}
}//主函式
public
class
threadwaitandnotify
}
列印結果(擷取部分):
輸出執行緒:jack...man
輸出執行緒:jack...man
輸出執行緒:jack...man
輸出執行緒:jack...man
輸出執行緒:傑克...男
輸出執行緒:傑克...男
輸出執行緒:傑克...男
執行緒安全問題是解決了,但是,跟我們預期的結果還是有些差距? 回到最初文章開頭我描述的場景,我們期望的結果是,輸入執行緒(input)順利對操作資源(res)賦值完成後,輸出執行緒(output)馬上能夠列印輸入執行緒的結果。
如下:
輸出執行緒:jack...man
輸出執行緒:傑克...男
輸出執行緒:jack...man
輸出執行緒:傑克...男
輸出執行緒:jack...man
輸出執行緒:傑克...男
輸出執行緒:jack...man..
.
為什麼我們解決了執行緒安全問題,但是沒達到我們想要的結果呢?
分析這個原因也很簡單 : 當輸入執行緒(input)操作資源(res)完成後,假設輸入執行緒(input)這時候失去執行權,而輸出執行緒(output)在短時間內得到了執行權,就會瘋狂列印這個結果。如何解決呢?這個涉及到乙個知識點,執行緒的等待喚醒機制。下篇博文介紹。
本篇博文相關**放這裡
java再複習 執行緒的安全問題以及同步
使用多執行緒,最重要的就是安全問題,何為安全問題?public class threadtest1 class myrunnable implements runnable catch interruptedexception e system.out.println i 執行結果 87 6543 ...
多執行緒安全問題 同步方法
2 同步方法 同步方法是指進入該方法時需要獲取this 物件的同步鎖,在方法上使用 synchronized 關鍵字,使用this 物件作為鎖,也就是使用了當前物件,因為鎖住了方法,所以相對於代 碼塊來說效率相對較低。注 靜態同步方法的鎖是該方法所在的類的位元組碼檔案物件,即類名.class 檔案 ...
Java學習筆記 執行緒安全問題
1 多執行緒的實現 1 繼承thread類 主函式中通過建立多個subthread類物件,並呼叫其start 方法。subthread類物件中屬性資料獨佔。2 實現runnable介面 主函式中建立乙個runnable介面實現類物件,同時建立多個thread類物件,並傳入介面物件,通過各thread...