线程带来的风险
線程安全性問題
多線程環境下 +多個線程共享一個資源+對資源進行非原子性操作。
以上三者都存在就會發生線程安全性問題
如文中的賣火車票問題:http://blog.csdn.net/zengmingen/article/details/53217229
原因是:一行java代碼轉成.class字節碼文件后是多行的,程序在執行的時候,行字節碼文件里一行行執行。
當多個線程,A線程執行到100行,cpu時間片用完了,保留現場,cpu去了服務B線程了。
B線程執行也執行到了100行,cpu時間片用完了,保留現場,cpu去了服務C線程了。
下一輪時間片的時候,可能A,B的取值是一樣的。
活躍性問題
死鎖
經典的哲學家吃飯問題
5個哲學家坐一起邊討論哲學邊吃飯,但是每個哲學家只有一只筷子,吃飯時需要問旁邊的人借一只筷子。
正常是:一開始討論哲學,要吃的哲學家問旁邊的借一下筷子。
異常是:5位哲學家都停下討論一起吃飯,誰也不借筷子,全餓死了。
都有資源,都不釋放,導致無資源可用,死鎖!
java自帶的jconsole可以檢測死鎖
饑餓
餐廳就餐問題,餐廳賣飯窗口只有一個。一群沒素質的人不排隊硬擠,買到飯了也不走,結果后面擠不進去的,餓死了。
在線程里是優先級問題,優先級沒搞好。
高優先級吞噬所有低優先級的CPU時間片
線程被永久堵塞在一個等待進入同步塊的狀態
等待的線程永遠不被喚醒
如何盡量避免饑餓問題?
設置合理的優先級
使用鎖來代替synchronized
活鎖
活鎖,其實和鎖沒有必然關系。活鎖就像小貓追著自己的尾巴咬,雖然它一直在咬卻一直沒有咬到!活鎖就是指線程一直處于運行(RUNNABLE)狀態,但卻是在做無用功,而這個線程本身要完成的任務卻一直無法進展。活鎖的一個典型例子是某些重試機制(實現地有問題)導致一個交易(請求)被不斷地重試,而每次重試都是失敗的(線程在最無用功),這就導致其他失敗的交易無法得到重試的機會(任務無法進展)。性能問題
cpu分配給各線程的時間,叫做時間片。這個時間片的時間是非常短的。
cpu在時間片完成后,cpu在切換到下一個線程之前需要做一些工作,如保留現場。這個比較消耗cpu資源。
總結
- 上一篇: 白话说编程之java线程
- 下一篇: 16.char类型