本文目錄一覽:
JAVA死鎖
主線程保持着A對象的鎖意思就是主線程正在處理A對象,其他線程不能處理,要等待主線程結束之後其他線程才能處理A對象。
同理副線程正在處理B對象,A不能處理,所以主線程結束不了,一直在等待。
兩個線程都運行不下去了就叫做死鎖,程序崩潰。
加鎖的意思就是某線程正在處理某對象,其他線程不能處理。
手打不容易,明白不明白都給分吧- -、
北大青鳥java培訓:如何避免死鎖?
什麼是死鎖,如何避免死鎖?線程A需要資源X,而線程B需要資源Y,而雙方都掌握有對方所要的資源,這種情況稱為死鎖(deadlock),或死亡擁抱(thedeadlyembrace)。
在並發程序設計中,江蘇電腦培訓建議死鎖(deadlock)是一種十分常見的邏輯錯誤。
通過採用正確的編程方式,死鎖的發生不難避免。
死鎖的四個必要條件在計算機專業的教材中,通常都會介紹死鎖的四個必要條件。
這四個條件缺一不可,或者說只要破壞了其中任何一個條件,死鎖就不可能發生。
我們來複習一下,這四個條件是:互斥(Mutualexclusion):存在這樣一種資源,它在某個時刻只能被分配給一個執行緒(也稱為線程)使用;持有(Holdandwait):當請求的資源已被佔用從而導致執行緒阻塞時,資源佔用者不但無需釋放該資源,而且還可以繼續請求更多資源;不可剝奪(Nopreemption):執行緒獲得到的互斥資源不可被強行剝奪,換句話說,只有資源佔用者自己才能釋放資源;環形等待(Circularwait):若干執行緒以不同的次序獲取互斥資源,從而形成環形等待的局面,想象在由多個執行緒組成的環形鏈中,每個執行緒都在等待下一個執行緒釋放它持有的資源。
解除死鎖的必要條件不難看出,在死鎖的四個必要條件中,第二、三和四項條件比較容易消除。
通過引入事務機制,往往可以消除第二、三兩項條件,方法是將所有上鎖操作均作為事務對待,一旦開始上鎖,即確保全部操作均可回退,同時通過鎖管理器檢測死鎖,並剝奪資源(回退事務)。
這種做法有時會造成較大開銷,而且也需要對上鎖模式進行較多改動。
消除第四項條件是比較容易且代價較低的辦法。
具體來說這種方法約定:上鎖的順序必須一致。
具體來說,我們人為地給鎖指定一種類似“水位”的方向性屬性。
無論已持有任何鎖,該執行緒所有的上鎖操作,必須按照一致的先後順序從低到高(或從高到低)進行,且在一個系統中,只允許使用一種先後次序。
請注意,放鎖的順序並不會導致死鎖。
也就是說,儘管按照鎖A,鎖B,放A,放B這樣的順序來進行鎖操作看上去有些怪異,但是只要大家都按先A後B的順序上鎖,便不會導致死鎖。
解決方法:1使用事務時,盡量縮短事務的邏輯處理過程,及早提交或回滾事務(細化處理邏輯,執行一段邏輯後便回滾或者提交,然後再執行其它邏輯,直到事物執行完畢提交);2設置死鎖超時參數為合理範圍,如:3分鐘-10分種;超過時間,自動放棄本次操作,避免進程懸掛; 3優化程序,檢查並避免死鎖現象出現; 4對所有的腳本和SP都要仔細測試,在正是版本之前。
5所有的SP都要有錯誤處理(通過@error) 6一般不要修改SQLSERVER事務的默認級別。
不推薦強行加鎖另外參考的解決方法:按同一順序訪問對象如果所有並發事務按同一順序訪問對象,則發生死鎖的可能性會降低。
例如,如果兩個並發事務獲得Supplier表上的鎖,然後獲得Part表上的鎖,則在其中一個事務完成之前,另一個事務被阻塞在Supplier表上。
第一個事務提交或回滾後,第二個事務繼續進行。
不發生死鎖。
將存儲過程用於所有的數據修改可以標準化訪問對象的順序。
北大青鳥java培訓:在Java程序中處理數據庫超時與死鎖?
每個使用關係型數據庫的程序都可能遇到數據死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與數據庫事務死鎖等情況相關的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與為例進行講解。
什麼是數據庫鎖定與死鎖鎖定(Locking)發生在當一個事務獲得對某一資源的“鎖”時,這時,其他的事務就不能更改這個資源了,這種機制的存在是為了保證數據一致性;在設計與數據庫交互的程序時,必須處理鎖與資源不可用的情況。
鎖定是個比較複雜的概念,仔細說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味着如果一個資源被鎖定,它總會在以後某個時間被釋放。
而死鎖發生在當多個進程訪問同一數據庫時,其中每個進程擁有的鎖都是其他進程所需的,由此造成每個進程都無法繼續下去。
如何避免鎖我們可利用事務型數據庫中的隔離級別機制來避免鎖的創建,正確地使用隔離級別可使程序處理更多的並發事件(如允許多個用戶訪問數據),還能預防像丟失修改(LostUpdate)、讀“臟”數據(DirtyRead)、不可重複讀(NonrepeatableRead)及“虛”(Phantom)等問題。
隔離級別問題現象丟失修改讀“臟”數據不可重複讀“虛”可重複讀取NoNoNoNo讀取穩定性NoNoNoYes光標穩定性NoNoYesYes未提交的讀NoYesYesYes表1:DB2的隔離級別與其對應的問題現象在只讀模式中,就可以防止鎖定發生,而不用那些未提交只讀隔離級別的含糊語句。
浙江電腦培訓發現一條SQL語句當使用了下列命令之一時,就應該考慮只讀模式了
Java Swing多線程死鎖問題解析
在基於Java Swing進行圖形界面開發的時候 經常遇到的就是Swing多線程問題 我們可以想想一下 如果需要在一個圖形界面上顯示很多數據 這些數據是經過長時間 複雜的查詢和運算得到的 如果在圖形界面的同一個線程中進行查詢和運算工作則會導致一段時間界面處於死機狀態 這會給用戶帶來不良的互動感受 為了解決這個問題 一般會單獨啟動一個線程進行運算和查詢工作 並隨時更新圖形界面 這時候 另一個問題就出現了 可能不僅沒有解決原來偶爾死機問題 還可能導致程序徹底死掉 幸運的是在JDK中暗藏了一個中斷程序的快捷鍵 就是CTRL+BREAK 這個快捷鍵Sun並沒有在文檔中公布 如果在命令行模式下啟動Java程序 然後按CTRL+BREAK鍵 會得到堆棧的跟蹤信息 從這些跟蹤信息中就可以知道具體引發死機的位置了
當一個程序產生死鎖的時候 你一定會希望儘快找到原因並且解決它 這時候 你一般的精力會用在查找引發死鎖的位置 另一半的精力會用於對堆棧進行跟蹤一確定引發死鎖的原因 但是在Java Swing程序中 你的所有努力可能都是沒有價值的 這是因為Java對Swing的多線程編程有一個特殊要求 就是在Swing里 只能在與Swing相同的線程里對GUI元件進行修改
也就是說 如果你要執行類似於jLabel setText( blabla )代碼 必須在Swing線程中 而不允許在其他線程當中 如果必須在其他線程中修改元件 可以使用類似一下方式解決
SwingUtilities invokeLater(new Runnable() {
public void run() {
jLabel setText( blabla );
}
}
invokeLater方法雖然表面有時間延遲執行含義 但是實際上幾乎沒有任何影響 可能在幾毫秒之內就會被執行 另外還有一個invokeAndWait方法 除非特殊需要 否則幾乎是不用的
在不使用invokeLater的情況下 導致刷新問題是可以理解的 但是導致死鎖就優點令人匪夷所思了 幸運的是 不是任何時候都需要調用改方法 這是因為大多數情況下 我們都是在與Swing同一個線程里進行界面更新 例如監聽按鈕點擊事件的ActionListener actionPerformed方法就是運行在與Swing相同的線程中的 但是如果在回調類中引用了另一個類 並且是不屬於AWT/Swing的 那麼結果就很難確定了 所以說使用invokeLater應該是最安全的
需要注意的是 在invokeLater做的任何事情 都會導致Swing線程窗口繪製工作暫停下來 等候invokeLater工作結束 所以不要在invokeLater進行耗時操作 盡量只執行那些界面繪製相關的工作 可以通過代碼重構 將那些與界面更新相關的代碼集中起來統一處理
lishixinzhi/Article/program/Java/gj/201311/27498
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/243077.html