死鎖定義:死鎖是指兩個或兩個以上的進程在執行過程當中,因爲競爭資源或者因爲彼此通訊而形成的一種阻塞現象,若無外力做用,它們都將沒法推動下去,此時稱系統處於死鎖狀態或系統產生了死鎖,這些永遠在相互等待的進程稱爲死鎖進程。ide
例子:哲學家進餐問題函數
死鎖產生的必要條件:this
破壞產生死鎖的任何一個必要條件均可以消除死鎖現象。spa
寫一個簡單的死鎖程序:線程
package com.fpc.Test; class thread1 implements Runnable { private DeadLock deadlock; //構造函數 public thread1( DeadLock deadlock ) { this.deadlock = deadlock; } @Override public void run( ) { try { deadlock.lock1toLock2(); } catch( Exception e ) { e.printStackTrace(); } } } class thread2 implements Runnable { private DeadLock deadlock; //構造函數 public thread2( DeadLock deadlock ) { this.deadlock = deadlock; } @Override public void run( ) { try { deadlock.lock2toLock1(); } catch( Exception e ) { e.printStackTrace(); } } } public class DeadLock { private Object lock1 = new Object(); private Object lock2 = new Object(); public void lock1toLock2() { synchronized( lock1 ) { try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized( lock2 ) { System.out.println("lock1toLock2 end....."); } } } public void lock2toLock1() { synchronized( lock2 ) { try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } synchronized( lock1 ) { System.out.println("lock2toLock1 end....."); } } } public static void main( String[] args ) { DeadLock d = new DeadLock(); thread1 t1 = new thread1(d); thread2 t2 = new thread2(d); Thread th1 = new Thread(t1); Thread th2 = new Thread(t2); th1.start(); th2.start(); } }
怎麼去分析死鎖:設計
先用jps命令查看虛機中運行的Java線程的pid:3d
而後根據pid 去查看 jstack pid:code
避免死鎖的方式對象
1.設計時考慮清楚鎖的順序,儘可能減小嵌套的加鎖交互數量blog
2.死鎖產生的緣由是資源的循環等待,那麼給獲取鎖加個時間限制,超過必定的時間尚未獲取到對象的鎖,那麼就釋放已經獲取的對象的鎖。固然synchronized是沒法作到的,能夠用可重入鎖ReentrantLock
針對上面的程序能夠這麼改:
public void lock1toLock2() throws InterruptedException { if (lock1.tryLock(3000, TimeUnit.MILLISECONDS)){ try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if ( lock2.tryLock(3000, TimeUnit.MICROSECONDS) ) { System.out.println("lock1toLock2 end....."); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
運行再次查看jps:能夠看到沒有出現DeadLock線程了,嗯,不會出現死鎖了