本文目錄一覽:
- 1、java中關於死鎖問題,我們new了兩個對象分別啟動為什麼還會出現死鎖問題
- 2、JAVA中,線程死鎖是什麼意思
- 3、java多線程中的死鎖,活鎖,飢餓,無鎖都是什麼鬼
- 4、北大青鳥java培訓:在Java程序中處理數據庫超時與死鎖?
- 5、在java中,死鎖形成的原因是?
- 6、數據庫為什麼總是產生死鎖
java中關於死鎖問題,我們new了兩個對象分別啟動為什麼還會出現死鎖問題
就是因為你有兩個對象才發生了死鎖啊,t1開始,然後t2開始,然後t1鎖住了o2直到他能使用o1,但是這個時候o1是被t2鎖住了,直到他能使用o2,但是o2是被t1鎖住了,然後就死鎖了,就是因為你用了兩個對象,他們分別一人鎖了一個對象,所以就死鎖了,假如你只new了一個對象,這個程序都是不會發生死鎖的。
JAVA中,線程死鎖是什麼意思
一. 什麼是線程
在談到線程死鎖的時候,我們首先必須了解什麼是Java線程。一個程序的進程會包含多個線程,一個線程就是運行在一個進程中的一個邏輯流。多線程允許在程序中並發執行多個指令流,每個指令流都稱為一個線程,彼此間互相獨立。
線程又稱為輕量級進程,它和進程一樣擁有獨立的執行控制,由操作系統負責調度,區別在於線程沒有獨立的存儲空間,而是和所屬進程中的其它線程共享一個存儲空間,這使得線程間的通信較進程簡單。筆者的經驗是編寫多線程序,必須注意每個線程是否干擾了其他線程的工作。每個進程開始生命周期時都是單一線程,稱為「主線程」,在某一時刻主線程會創建一個對等線程。如果主線程停滯則系統就會切換到其對等線程。和一個進程相關的線程此時會組成一個對等線程池,一個線程可以殺死其任意對等線程。
因為每個線程都能讀寫相同的共享數據。這樣就帶來了新的麻煩:由於數據共享會帶來同步問題,進而會導致死鎖的產生。
二. 死鎖的機制
由多線程帶來的性能改善是以可靠性為代價的,主要是因為有可能產生線程死鎖。死鎖是這樣一種情形:多個線程同時被阻塞,它們中的一個或者全部都在等待某個資源被釋放。由於線程被無限期地阻塞,因此程序不能正常運行。簡單的說就是:線程死鎖時,第一個線程等待第二個線程釋放資源,而同時第二個線程又在等待第一個線程釋放資源。這裡舉一個通俗的例子:如在人行道上兩個人迎面相遇,為了給對方讓道,兩人同時向一側邁出一步,雙方無法通過,又同時向另一側邁出一步,這樣還是無法通過。假設這種情況一直持續下去,這樣就會發生死鎖現象。
導致死鎖的根源在於不適當地運用「synchronized」關鍵詞來管理線程對特定對象的訪問。「synchronized」關鍵詞的作用是,確保在某個時刻只有一個線程被允許執行特定的代碼塊,因此,被允許執行的線程首先必須擁有對變量或對象的排他性訪問權。當線程訪問對象時,線程會給對象加鎖,而這個鎖導致其它也想訪問同一對象的線程被阻塞,直至第一個線程釋放它加在對象上的鎖。
Java中每個對象都有一把鎖與之對應。但Java不提供單獨的lock和unlock操作。下面筆者分析死鎖的兩個過程「上鎖」和「鎖死」 。
(1) 上鎖
許多線程在執行中必須考慮與其他線程之間共享數據或協調執行狀態,就需要同步機制。因此大多數應用程序要求線程互相通信來同步它們的動作,在 Java 程序中最簡單實現同步的方法就是上鎖。在 Java 編程中,所有的對象都有鎖。線程可以使用 synchronized 關鍵字來獲得鎖。在任一時刻對於給定的類的實例,方法或同步的代碼塊只能被一個線程執行。這是因為代碼在執行之前要求獲得對象的鎖。
為了防止同時訪問共享資源,線程在使用資源的前後可以給該資源上鎖和開鎖。給共享變量上鎖就使得 Java 線程能夠快速方便地通信和同步。某個線程若給一個對象上了鎖,就可以知道沒有其他線程能夠訪問該對象。即使在搶佔式模型中,其他線程也不能夠訪問此對象,直到上鎖的線程被喚醒、完成工作並開鎖。那些試圖訪問一個上鎖對象的線程通常會進入睡眠狀態,直到上鎖的線程開鎖。一旦鎖被打開,這些睡眠進程就會被喚醒並移到準備就緒隊列中。
(2)鎖死
如果程序中有幾個競爭資源的並發線程,那麼保證均衡是很重要的。系統均衡是指每個線程在執行過程中都能充分訪問有限的資源,系統中沒有餓死和死鎖的線程。當多個並發的線程分別試圖同時佔有兩個鎖時,會出現加鎖衝突的情形。如果一個線程佔有了另一個線程必需的鎖,互相等待時被阻塞就有可能出現死鎖。
在編寫多線程代碼時,筆者認為死鎖是最難處理的問題之一。因為死鎖可能在最意想不到的地方發生,所以查找和修正它既費時又費力。例如,常見的例子如下面這段程序。
public int sumArrays(int[] a1, int[] a2) …{ int value = 0; int size = a1.length; if (size == a2.length) …{ synchronized(a1) …{ //1 synchronized(a2) …{ //2 for (int i=0; isize; i++) value += a1[i] + a2[i]; } } } return value; }
這段代碼在求和操作中訪問兩個數組對象之前鎖定了這兩個數組對象。它形式簡短,編寫也適合所要執行的任務;但不幸的是,它有一個潛在的問題。這個問題就是它埋下了死鎖的種子。
沒有完結,請樓主看下面的網址。
java多線程中的死鎖,活鎖,飢餓,無鎖都是什麼鬼
死鎖發生在當一些進程請求其它進程佔有的資源而被阻塞時。
另外一方面,活鎖不會被阻塞,而是不停檢測一個永遠不可能為真的條件。除去進程本身持有的資源外,活鎖狀態的進程會持續耗費寶貴的CPU時間。
最後,進程會處於飢餓狀態是因為持續地有其它優先級更高的進程請求相同的資源。不像死鎖或者活鎖,飢餓能夠被解開。例如,當其它高優先級的進程都終止時並且沒有更高優先級的進程到達。
北大青鳥java培訓:在Java程序中處理數據庫超時與死鎖?
每個使用關係型數據庫的程序都可能遇到數據死鎖或不可用的情況,而這些情況需要在代碼中編程來解決;本文主要介紹與數據庫事務死鎖等情況相關的重試邏輯概念,此外,還會探討如何避免死鎖等問題,文章以DB2(版本9)與為例進行講解。
什麼是數據庫鎖定與死鎖鎖定(Locking)發生在當一個事務獲得對某一資源的「鎖」時,這時,其他的事務就不能更改這個資源了,這種機制的存在是為了保證數據一致性;在設計與數據庫交互的程序時,必須處理鎖與資源不可用的情況。
鎖定是個比較複雜的概念,仔細說起來可能又需要一大篇,所以在本文中,只把鎖定看作是一個臨時事件,這意味着如果一個資源被鎖定,它總會在以後某個時間被釋放。
而死鎖發生在當多個進程訪問同一數據庫時,其中每個進程擁有的鎖都是其他進程所需的,由此造成每個進程都無法繼續下去。
如何避免鎖我們可利用事務型數據庫中的隔離級別機制來避免鎖的創建,正確地使用隔離級別可使程序處理更多的並發事件(如允許多個用戶訪問數據),還能預防像丟失修改(LostUpdate)、讀「臟」數據(DirtyRead)、不可重複讀(NonrepeatableRead)及「虛」(Phantom)等問題。
隔離級別問題現象丟失修改讀「臟」數據不可重複讀「虛」可重複讀取NoNoNoNo讀取穩定性NoNoNoYes光標穩定性NoNoYesYes未提交的讀NoYesYesYes表1:DB2的隔離級別與其對應的問題現象在只讀模式中,就可以防止鎖定發生,而不用那些未提交只讀隔離級別的含糊語句。
湖北電腦培訓發現一條SQL語句當使用了下列命令之一時,就應該考慮只讀模式了
在java中,死鎖形成的原因是?
死鎖是進程死鎖的簡稱,是由Dijkstra於1965年研究銀行家算法時首先提出來的。它是計算機操作系統乃至並發程序設計中最難處理的問題之一。實際上,死鎖問題不僅在計算機系統中存在,在我們日常生活中它也廣泛存在。
1.什麼是死鎖
我們先看看這樣一個生活中的例子:在一條河上有一座橋,橋面較窄,只能容納一輛汽車通過,無法讓兩輛汽車並行。如果有兩輛汽車A和B分別由橋的兩端駛上該橋,則對於A車來說,它走過橋面左面的一段路(即佔有了橋的一部分資源),要想過橋還須等待B車讓出右邊的橋面,此時A車不能前進;對於B車來說,它走過橋面右邊的一段路(即佔有了橋的一部分資源),要想過橋還須等待A車讓出左邊的橋面,此時B車也不能前進。兩邊的車都不倒車,結果造成互相等待對方讓出橋面,但是誰也不讓路,就會無休止地等下去。這種現象就是死鎖。如果把汽車比做進程,橋面作為資源,那麽上述問題就描述為:進程A佔有資源R1,等待進程B佔有的資源Rr;進程B佔有資源Rr,等待進程A佔有的資源R1。而且資源R1和Rr只允許一個進程佔用,即:不允許兩個進程同時佔用。結果,兩個進程都不能繼續執行,若不採取其它措施,這種循環等待狀況會無限期持續下去,就發生了進程死鎖。
在計算機系統中,涉及軟件,硬件資源都可能發生死鎖。例如:系統中只有一台CD-ROM驅動器和一台打印機,某一個進程佔有了CD-ROM驅動器,又申請打印機;另一進程佔有了打印機,還申請CD-ROM。結果,兩個進程都被阻塞,永遠也不能自行解除。
所謂死鎖,是指多個進程循環等待它方佔有的資源而無限期地僵持下去的局面。很顯然,如果沒有外力的作用,那麽死鎖涉及到的各個進程都將永遠處於封鎖狀態。從上面的例子可以看出,計算機系統產生死鎖的根本原因就是資源有限且操作不當。即:一種原因是系統提供的資源太少了,遠不能滿足並發進程對資源的需求。這種競爭資源引起的死鎖是我們要討論的核心。例如:消息是一種臨時性資源。某一時刻,進程A等待進程B發來的消息,進程B等待進程C發來的消息,而進程C又等待進程A發來的消息。消息未到,A,B,C三個進程均無法向前推進,也會發生進程通信上的死鎖。另一種原因是由於進程推進順序不合適引發的死鎖。資源少也未必一定產生死鎖。就如同兩個人過獨木橋,如果兩個人都要先過,在獨木橋上僵持不肯後退,必然會應競爭資源產生死鎖;但是,如果兩個人上橋前先看一看有無對方的人在橋上,當無對方的人在橋上時自己才上橋,那麽問題就解決了。所以,如果程序設計得不合理,造成進程推進的順序不當,也會出現死鎖。
2.產生死鎖的必要條件
從以上分析可見,如果在計算機系統中同時具備下面四個必要條件時,那麽會發生死鎖。換句話說,只要下面四個條件有一個不具備,系統就不會出現死鎖。
〈1〉互斥條件。即某個資源在一段時間內只能由一個進程佔有,不能同時被兩個或兩個以上的進程佔有。這種獨佔資源如CD-ROM驅動器,打印機等等,必須在佔有該資源的進程主動釋放它之後,其它進程才能佔有該資源。這是由資源本身的屬性所決定的。如獨木橋就是一種獨佔資源,兩方的人不能同時過橋。
〈2〉不可搶佔條件。進程所獲得的資源在未使用完畢之前,資源申請者不能強行地從資源佔有者手中奪取資源,而只能由該資源的佔有者進程自行釋放。如過獨木橋的人不能強迫對方後退,也不能非法地將對方推下橋,必須是橋上的人自己過橋後空出橋面(即主動釋放佔有資源),對方的人才能過橋。
〈3〉佔有且申請條件。進程至少已經佔有一個資源,但又申請新的資源;由於該資源已被另外進程佔有,此時該進程阻塞;但是,它在等待新資源之時,仍繼續佔用已佔有的資源。還以過獨木橋為例,甲乙兩人在橋上相遇。甲走過一段橋面(即佔有了一些資源),還需要走其餘的橋面(申請新的資源),但那部分橋面被乙佔有(乙走過一段橋面)。甲過不去,前進不能,又不後退;乙也處於同樣的狀況。
〈4〉循環等待條件。存在一個進程等待序列{P1,P2,…,Pn},其中P1等待P2所佔有的某一資源,P2等待P3所佔有的某一源,……,而Pn等待P1所佔有的的某一資源,形成一個進程循環等待環。就像前面的過獨木橋問題,甲等待乙佔有的橋面,而乙又等待甲佔有的橋面,從而彼此循環等待。
上面我們提到的這四個條件在死鎖時會同時發生。也就是說,只要有一個必要條件不滿足,則死鎖就可以排除。
8.2 死鎖的預防
前面介紹了死鎖發生時的四個必要條件,只要破壞這四個必要條件中的任意一個條件,死鎖就不會發生。這就為我們解決死鎖問題提供了可能。一般地,解決死鎖的方法分為死鎖的預防,避免,檢測與恢復三種(注意:死鎖的檢測與恢復是一個方法)。我們將在下面分別加以介紹。
死鎖的預防是保證系統不進入死鎖狀態的一種策略。它的基本思想是要求進程申請資源時遵循某種協議,從而打破產生死鎖的四個必要條件中的一個或幾個,保證系統不會進入死鎖狀態。
數據庫為什麼總是產生死鎖
多線程是很容易造成死鎖,一般情況下死鎖都是因為並發操作引起的。我不懂JAVA,但死鎖這個問題每種開發工具和數據庫都會碰到.解決辦法是:
1、程序方面優化算法(如有序資源分配法、銀行算法等),在一個程序里,能不用多線程更新同一張數據庫表 盡量不要用,如果要用,其避免死鎖的算法就很複雜。
2、數據庫方面設置等待超時時間
3、發生死鎖後直接KILL掉數據庫進程
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/237241.html