物件的狀態:物件的狀態是指儲存在狀態變數(例項或靜態域)中的資料。物件的狀態還可能包括其他依賴物件的域。例如,hashmap的狀態不僅儲存在物件本身,還儲存在map.entry物件中。
多執行緒安全的概念:當多個執行緒訪問某個類時,不管執行時環境採用何種排程方式或者這些執行緒將如何交替執行,並且在主調**中不需要任何額外的同步或協同,這個類都能表現出正確的行為,那麼這個類就是執行緒安全的。
多執行緒安全的核心:編寫執行緒安全的**,核心在於要對狀態訪問操作進行管理,特別是對共享的(shared)和可變的(mutable)狀態的訪問。
1.無狀態物件執行緒安全
如例子中的因式分解servlet:
public
class statelessfactorizer implement servlet
}
它既不包含任何域,也不包含其他類中域的引用,所以他是無狀態的。因此每個執行緒執行的結果不會影響到其他執行緒。
2.盡可能使用現有的執行緒安全物件管理狀態
下面是訪問一次count+1的例子:
public
class unsafecountingfactorizer implement servlet
public
void
service(servletrequest req,servletresponse resp)
}
count++的操作是 讀取count的值 count+1 寫入count 三步,如果執行緒1執行到第二步還沒寫入count的時候,執行緒2開始執行了第一步,那麼執行緒2讀取的count是執行緒1還沒賦值的count,於是就出現的執行緒安全問題。
下面是解決方法:
public
class safecountingfactorizer implement servlet
public
void
service(servletrequest req,servletresponse resp)
}
通過用atomiclong來代替long型別的計數器,能夠確保所有對計數器狀態的訪問操作都是原子的。由於servlet的狀態只有乙個,也就是計數器的狀態,所以這個servlet是執行緒安全的。
3.防止競態條件的出現
競態條件:由於不恰當的執行時序而出現不正確的結果。常見的情況是延遲初始化。
public
class lazyinitrace
return instance;
}}
上面的競態條件很容易出現執行緒安全問題,如果執行緒1和2同時進入if語句,那麼這個單例模式不能達到它想要的效果。
下面是解決方法:
public
class lazyinitrace}}
return instance;
}}
這叫雙重鎖,他能保證new只會執行一次,保證了執行順序,所以競態條件就不存在了。而且我們要保證這個鎖是同乙個鎖。
4.對於多個變數的不變性條件,涉及的所有變數需要同乙個鎖保護。
下面的例子是快取因式分解結果,如果傳入值相同,返回快取值。
public
class unsafecountingfactorizer implement servletelse
}}
上面的例子,兩個狀態都是能保證原子性的,但是不變性條件同時包含兩個狀態,也就是只修改其中乙個變數,那麼在兩次修改操作之間,其他執行緒將發現不變性條件被破壞了。
解決方法:
public
class
unsafecountingfactorizer
implement
servlet
}if(factors == null)
}encodeingintoresponse(req,factorys);}}
}
重新構造了這個類之後,實現了簡單性和併發性的平衡,把同步**全部方法放在乙個synchronized可能會影響效率,而將同步**塊分解太小會影響簡單行和可讀性。
5.佔資源太多的操作不要持有鎖
例如,當乙個程式執行時間太長或者占有cpu資源太大,很可能會受到其他因素的影響,導致長時間持有鎖,導致其他程序長時間發生阻塞。
Java多執行緒之執行緒安全
當多個執行緒訪問某乙個類 物件或方法時 這個類始終都能表現出正確的行為,那麼這個類 物件或方法 就是執行緒安全的。public class mythread extends thread public static void main string args 結果如下 t1正在執行 4 t1正在執行...
執行緒安全性
定義 當多個執行緒訪問某個類時,不管執行環境採用何種呼叫方式或者這些執行緒如何交替執行,並且在主調 中不需要任何額外的同步或者協同,這個類都能表現出正確的行為,那麼就稱這個類是執行緒安全的。主要表現三個方面 atomic cas unsafe.compareandswapint atomiclong...
執行緒安全性
執行緒安全性 當多個執行緒訪問某個類時,這個類始終都能表現出正確的行為,那麼稱這個類是執行緒安全的。執行緒不安全產生的問題 競態條件 由於不恰當的執行時序而出現不正確的結果。大多數競態條件的本質是基於一種可能失效的觀察結果來做出判斷或者執行某個計算。常見先檢查後執行,延遲初始化 單例模式 讀取 修改...