以前咱們簡單的討論了一下關於Java
中的同步還有一些鎖優化的問題,今天咱們就來簡單的聊一聊關於Java
中的死鎖
問題。多線程
這個問題咱們在開發的時候,或多或少都能遇到,對業務邏輯沒有正確的梳理,又或者是在多線程的狀況下,對程序的執行順序有理解上的誤差等等,可是這種問題有時候執行代碼是看不出來的,那咱們今天就看一看如何使用簡單的命令來查看死鎖。ide
首先咱們得寫一段有問題的程序,固然前提條件是先要明確什麼是死鎖,這個問題在網上找有不少的資料,在這裏咱們就不重複敘述了,先來看一下代碼工具
class Lock extends Thread{ private String lock1; private String lock2; Lock(String s1, String s2){ this.lock1 = s1; this.lock2 = s2; } @Override public void run() { synchronized (lock1) { System.out.println(Thread.currentThread().getName() + " get " + lock1); try { Thread.sleep(1 * 1000); synchronized (lock2) { System.out.println(Thread.currentThread().getName() + " get -- " + lock2); } } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws InterruptedException { Thread thread1 = new Thread(new Lock(LOCK_1, LOCK_2)); Thread thread2 = new Thread(new Lock(LOCK_2, LOCK_1)); thread1.start(); thread2.start(); thread1.join(); thread2.join(); }
在這裏咱們用synchronized
來嵌套兩層,而後賦予兩個線程兩個交互的鎖,那麼這段代碼在大部分狀況下會發生死鎖,可是咱們的程序執行下來沒有報錯,那這個該如何查看呢?JDK
爲咱們提供了一些工具,咱們來看一下,首先用jps
這個命令查看當前的PID
,這個就和ps
命令差很少。優化
而後咱們再用jstack
來查看具體的棧信息,例如:jstack 9520
,會打印不少的信息,咱們看幾個比較重要的。this
這裏顯示兩個線程的狀態如今是處於阻塞狀態,而後都在等待鎖的獲取,咱們再繼續往下看。
這裏很明確的指出線程3在等待一個鎖獲取,可是這個鎖被線程1持有,反過來也是同樣,線程1也在等待一個鎖獲取,可是這個鎖又被線程3持有,那麼這裏就產生了一個死鎖。spa
JDK
的這些命令行工具能很好的幫助咱們分析程序中的一些問題,可是咱們在平常的開發工做中,該如何規避這些問題呢,其實個人建議只有一點,首先要明確理論,有了必定的理論作基礎,而後就是不斷的實踐採坑,這樣才能明白某些問題的點在哪裏。命令行