關於線程死鎖
什么是死鎖:
在編寫多線程的時候,必須要注意資源的使用問題,如果兩個或多個線程分別擁有不同的資源,
而同時又需要對方釋放資源才能繼續運行時,就會發生死鎖。
簡單來說:死鎖就是當一個或多個進程都在等待系統資源,而資源本身又被占用時,所產生的一種狀態。
造成死鎖的原因:
多個線程競爭共享資源,由於資源被占用,資源不足或進程推進順序不當等原因造成線程處於永久阻塞狀態,從而引發死鎖
--如果朋友您想轉載本文章請注明轉載地址"http://www.cnblogs.com/XHJT/p/3898970.html "謝謝--
當然死鎖的產生是必須要滿足一些特定條件的:
1.互斥條件:進程對於所分配到的資源具有排它性,即一個資源只能被一個進程占用,直到被該進程釋放
2.請求和保持條件:一個進程因請求被占用資源而發生阻塞時,對已獲得的資源保持不放。
3.不剝奪條件:任何一個資源在沒被該進程釋放之前,任何其他進程都無法對他剝奪占用
4.循環等待條件:當發生死鎖時,所等待的進程必定會形成一個環路(類似於死循環),造成永久阻塞。
代碼實例:
用兩個線程請求被對方占用的資源,實現線程死鎖
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,當兩個線程發出請求時,由於所請求的資源都在對方手中,從而發生線程阻塞,造成了線程的死鎖。
解決方法
要預防和避免死鎖的發生,只需將上面所講到的4個條件破壞掉其中之一即可。
如上面的代碼當中,由於有四個同步代碼塊,代表着線程要占用的資源,只需要將其中一個同步代碼塊去掉,即可解決死鎖問題。
一般而言破壞“循環等待”這個條件是解決死鎖最有效的方法
