線程通訊,主要經過共享訪問進程資源。這種通訊方式很是高效,但存在兩個問題:線程衝突(thread interference) , 內存一致性錯誤(memory consistensy errors)。java
解決這兩種問題的方法是 線程同步(thread synchronization)。在介紹線程同步以前,先來了解一下這兩個問題。c++
這篇文章先介紹第一個問題:線程衝突。線程
當兩個運行在不一樣線程的操做,做用在同一個數據上,會發生線程衝突 (Thread interference)code
這也意味着,兩個操做分別由多個步驟組成,且兩個操做同時執行,會致使步驟交疊進程
這裏有一個類 Counter
內存
class Counter { private int c = 0; public void increment() { c++; } public void decrement() { c--; } public int value() { return c; } }
看起來,Counter
中的操做不會產生交疊。好比increment()
方法中,惟一的 statement 是c++
。資源
然而,即便是一個簡單的 statement,在JVM中也會轉換爲多個步驟 —— 即該 statement 非原子操做rem
一個簡單的 statement c++
,能夠簡單分爲三步 ( c--
同理 )同步
取出當前c
的值io
將取出的值增長1
將取出的值存儲至c
(覆蓋原值)
假設,線程A調用increment()
的同時,線程B調用decrement()
。則兩個操做可能產生以下交疊
Thread A: 取出 c.
Thread B: 取出 c.
Thread A: 將取出的值增長 1.
Thread B: 將取出的值減小 -1.
Thread A: 將取出的值存儲至 c; c == 1.
Thread B: 將取出的值存儲至 c; c == -1.
線程A的結果丟失,被線程B的結果覆蓋。這是一種可能的結果,也可能線程B的結果被A覆蓋;或沒有交疊,
不發生錯誤 —— 線程衝突 的結果不可預料,bug很難被發現而且修復