Java 面試大全〖十〗死鎖產生及排查
死鎖是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,薦無外力干涉那它們都將無法推進下去,如果系統資源充足,進程的資源請求都能夠得到滿足,死鎖出現的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。
產生死鎖
package JUC;
import java.util.concurrent.TimeUnit;
class LockDemo implements Runnable{
private String lockA;
private String lockB;
public LockDemo(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA){
System.out.println(Thread.currentThread().getName()+"\t"+"自己持有: "+lockA+"嘗試獲得:" +lockB);
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
synchronized (lockB){
System.out.println(Thread.currentThread().getName()+"\t"+"自己持有: "+lockB+"嘗試獲得:" +lockA);
}
}
}
}
public class DeadLock {
public static void main(String[] args) {
String lockA="lockA";
String lockB="lockB";
new Thread(new LockDemo(lockA,lockB),"aaa").start();
new Thread(new LockDemo(lockB,lockA),"bbb").start();
}
}
上面產生了一個死鎖,下面我們來看怎麼分析
- 產生阻塞的原因有很多,你怎麼確定是死鎖導致的呢?
這裏我們藉助java自帶的一個命令 jps 來查看當前運行的java程序,一步一步排除分析
這裏對應着我們的程序裏有個pid,拿到pid即可排查
-
1、Jstack命令
jstack是java虛擬機自帶的一種堆棧跟蹤工具。jstack用於打印出給定的java進程ID或core file或遠程調試服務的Java堆棧信息。 Jstack工具可以用於生成java虛擬機當前時刻的線程快照。線程快照是當前java虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待等。 線程出現停頓的時候通過jstack來查看各個線程的調用堆棧,就可以知道沒有響應的線程到底在後臺做什麼事情,或者等待什麼資源。 -
2、JConsole工具
Jconsole是JDK自帶的監控工具,在JDK/bin目錄下可以找到。它用於連接正在運行的本地或者遠程的JVM,對運行在Java應用程序的資源消耗和性能進行監控,並畫出大量的圖表,提供強大的可視化界面。而且本身佔用的服務器內存很小,甚至可以說幾乎不消耗。 ------
使用jstack來打印java運行時異常棧