淺談Java中鎖的問題

以前咱們簡單的討論了一下關於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命令差很少。優化

clipboard.png

而後咱們再用jstack來查看具體的棧信息,例如:jstack 9520,會打印不少的信息,咱們看幾個比較重要的。this

clipboard.png

這裏顯示兩個線程的狀態如今是處於阻塞狀態,而後都在等待鎖的獲取,咱們再繼續往下看。
clipboard.png
這裏很明確的指出線程3在等待一個鎖獲取,可是這個鎖被線程1持有,反過來也是同樣,線程1也在等待一個鎖獲取,可是這個鎖又被線程3持有,那麼這裏就產生了一個死鎖。spa

JDK的這些命令行工具能很好的幫助咱們分析程序中的一些問題,可是咱們在平常的開發工做中,該如何規避這些問題呢,其實個人建議只有一點,首先要明確理論,有了必定的理論作基礎,而後就是不斷的實踐採坑,這樣才能明白某些問題的點在哪裏。命令行

相關文章
相關標籤/搜索