關於線程死鎖java
什麼是死鎖:多線程
在編寫多線程的時候,必需要注意資源的使用問題,若是兩個或多個線程分別擁有不一樣的資源,
而同時又須要對方釋放資源才能繼續運行時,就會發生死鎖。ide
簡單來講:死鎖就是當一個或多個進程都在等待系統資源,而資源自己又被佔用時,所產生的一種狀態。學習
形成死鎖的緣由:
多個線程競爭共享資源,因爲資源被佔用,資源不足或進程推動順序不當等緣由形成線程處於永久阻塞狀態,從而引起死鎖線程
固然死鎖的產生是必需要知足一些特定條件的:
1.互斥條件:進程對於所分配到的資源具備排它性,即一個資源只能被一個進程佔用,直到被該進程釋放
2.請求和保持條件:一個進程因請求被佔用資源而發生阻塞時,對已得到的資源保持不放。
3.不剝奪條件:任何一個資源在沒被該進程釋放以前,任何其餘進程都沒法對他剝奪佔用
4.循環等待條件:當發生死鎖時,所等待的進程一定會造成一個環路(相似於死循環),形成永久阻塞。blog
代碼實例:
用兩個線程請求被對方佔用的資源,實現線程死鎖進程
package com.xhj.thread; /** * 用兩個線程請求被對方佔用的資源,實現線程死鎖 * * @author XIEHEJUN * */ public class DeadLockThread implements Runnable { private static final Object objectA = new Object(); private static final Object objectB = new Object(); private boolean flag; @Override public void run() { String threadName = Thread.currentThread().getName(); System.out.println("當前線程 爲:" + threadName + "\tflag = " + flag); if (flag) { synchronized (objectA) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(threadName + "已進入同步代碼塊objectA,準備進入objectB"); synchronized (objectB) { System.out.println(threadName + "已經進入同步代碼塊objectB"); } } } else { synchronized (objectB) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(threadName + "已進入同步代碼塊objectB,準備進入objectA"); synchronized (objectA) { System.out.println(threadName + "已經進入同步代碼塊objectA"); } } } } public static void main(String[] args) { DeadLockThread deadlock1 = new DeadLockThread(); DeadLockThread deadlock2 = new DeadLockThread(); deadlock1.flag = true; deadlock2.flag = false; Thread thread1 = new Thread(deadlock1); Thread thread2 = new Thread(deadlock2); thread1.start(); thread2.start(); } }
注:上面代碼中創建了兩個線程,線程thread1佔有資源objectA,線程thread2佔有資源objectB,當兩個線程發出請求時,因爲所請求的資源都在對方手中,從而發生線程阻塞,形成了線程的死鎖。資源
解決方法get
要預防和避免死鎖的發生,只需將上面所講到的4個條件破壞掉其中之一便可。同步
如上面的代碼當中,因爲有四個同步代碼塊,表明着線程要佔用的資源,只須要將其中一個同步代碼塊去掉,便可解決死鎖問題。
通常而言破壞「循環等待」這個條件是解決死鎖最有效的方法