這樣的執行機制就可能會導致多執行緒的安全問題:
1.多個執行緒操作共享資料
2.在乙個執行緒中有多行**操作共享資料(改變共享資料)
解決思路:乙個執行緒在執行執行緒任務的時候將多條操作共享資料的**一起執行,在執行過程中不允許其他執行緒執行
**體現:
package thread;
class tickets implements runnable catch (interruptedexception e) //沒有解決方案
system.out.println(thread.currentthread().getname() + " " + --ticket);}}
}}}public class threadselltickets
}
將多行**封裝成**塊來解決,這個**塊叫同步**塊synchronized
使用格式:
synchronized(物件)//物件的任意的(一般使用object obj = new object() )
需要同步進行的**
執行解析://還是根據售票那個例子
比如執行緒1 得到了cpu的執行權,讀到synchronized 會判斷物件是否存在,如果物件存在,會拿取物件再執行**塊中的**。在執行**塊中的**時cpu有可能會切換出去,切換到其他執行緒,其他執行緒也會執行到synchronized 判斷物件是否存在,但是物件已經被執行緒一拿走,物件不存在,此執行緒就不會執行**塊中的**。當執行緒1 中同步**塊執行完成,獲取的物件才會被釋放,其他的執行緒才能執行**塊中的**。
synchronized(物件)相當於乙個鎖,執行緒判斷物件是否存在,存在就拿走就相當於將這段**塊的門鎖上(鑰匙被拿走),雖然cpu的執行權會切換出去但是其他執行緒到這判斷後發現物件不存在,門被鎖起來了,無法繼續執行**塊中的**,只有當執行緒執行完同步**塊,物件才會被釋放(鑰匙被釋放),這段**塊的門才能被其他執行緒開啟
執行緒產生安全問題的根本原因:cpu的切換,乙個執行緒沒有將任務執行完(一次)cpu就切換出去,另乙個執行緒又會修改共享資料,從而產生了資料的錯誤。而鎖機制解決這一問題的方式就是執行緒來執行這個任務時就將任務鎖起來,無論cpu如何切換,只有一條路徑將這個任務執行完(操作共享資料的**執行完),鎖才會開啟)
同步的前提:(什麼時候使用同步)
有時候加了同步問題也沒有辦法解決。
1.存在多個執行緒。沒有多個執行緒也不存在cpu執行權切換的事
2.多執行緒使用的鎖要是一樣的,物件要是一樣的,不是一樣的鎖你也不存在鎖住,鎖不一樣你也鎖不住
如果加上了同步鎖還是無法解決多執行緒的安全問題,就要從同步鎖的前提去思考是否寫錯了
同步的**行,是對共享資料操作(修改)的**行。首先一定要明確共享資料在**
多執行緒安全問題
這裡的安全問題可以理解為 實現在邏輯上的問題,比如 火車站賣票 100張票讓4個人去賣,一定不能出現賣的票是負數問題,那麼開啟多執行緒後,如何才能保證賣的票不可能存在負數呢?常用的解決方法有兩種 1,使用同步 塊,把需要同步的 再放同步 塊中 2,使用同步函式 同步的鎖,可以理解為就是那個物件!同步...
Java 多執行緒存在的安全問題
存在的問題 當num 1時,假如執行緒t1此時拿到cpu,執行任務 在判斷if語句條件剛剛結束時,也就是還沒來得及執行輸出語句,cpu被t2搶走了,此時num依然等於1,那麼if條件通過,在執行過程中,依然可能被其他執行緒搶走cpu而進入阻塞狀態,最後有可能賣出0,1,2這種票,這就是多執行緒存在的...
Java多執行緒的安全問題(02)
要求 在電影院有三個視窗同時賣電影票 50張 啟動3條執行緒,每1條執行緒代表乙個售票視窗。1 定義賣票的執行緒。class saleticketthread extends thread override public void run else 因為多個視窗共享著這50張票,所以設定num成員屬...