摘要:之前我們簡(jiǎn)單的討論了一下關(guān)于中的同步還有一些鎖優(yōu)化的問(wèn)題,今天我們就來(lái)簡(jiǎn)單的聊一聊關(guān)于中的死鎖問(wèn)題。這里顯示兩個(gè)線程的狀態(tài)現(xiàn)在是處于阻塞狀態(tài),然后都在等待鎖的獲取,我們?cè)倮^續(xù)往下看。
之前我們簡(jiǎn)單的討論了一下關(guān)于Java中的同步還有一些鎖優(yōu)化的問(wèn)題,今天我們就來(lái)簡(jiǎn)單的聊一聊關(guān)于Java中的死鎖問(wèn)題。
這個(gè)問(wèn)題我們?cè)陂_(kāi)發(fā)的時(shí)候,或多或少都能遇到,對(duì)業(yè)務(wù)邏輯沒(méi)有正確的梳理,又或者是在多線程的情況下,對(duì)程序的執(zhí)行順序有理解上的偏差等等,但是這種問(wèn)題有時(shí)候執(zhí)行代碼是看不出來(lái)的,那我們今天就看一看如何使用簡(jiǎn)單的命令來(lái)查看死鎖。
首先我們得寫(xiě)一段有問(wèn)題的程序,當(dāng)然前提條件是先要明確什么是死鎖,這個(gè)問(wèn)題在網(wǎng)上找有很多的資料,在這里我們就不重復(fù)敘述了,先來(lái)看一下代碼
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來(lái)嵌套兩層,然后賦予兩個(gè)線程兩個(gè)交互的鎖,那么這段代碼在大部分情況下會(huì)發(fā)生死鎖,但是我們的程序執(zhí)行下來(lái)沒(méi)有報(bào)錯(cuò),那這個(gè)該如何查看呢?JDK為我們提供了一些工具,我們來(lái)看一下,首先用jps這個(gè)命令查看當(dāng)前的PID,這個(gè)就和ps命令差不多。
然后我們?cè)儆?b>jstack來(lái)查看具體的棧信息,例如:jstack 9520,會(huì)打印很多的信息,我們看幾個(gè)比較重要的。
這里顯示兩個(gè)線程的狀態(tài)現(xiàn)在是處于阻塞狀態(tài),然后都在等待鎖的獲取,我們?cè)倮^續(xù)往下看。
這里很明確的指出線程3在等待一個(gè)鎖獲取,但是這個(gè)鎖被線程1持有,反過(guò)來(lái)也是一樣,線程1也在等待一個(gè)鎖獲取,但是這個(gè)鎖又被線程3持有,那么這里就產(chǎn)生了一個(gè)死鎖。
JDK的這些命令行工具能很好的幫助我們分析程序中的一些問(wèn)題,但是我們?cè)谌粘5拈_(kāi)發(fā)工作中,該如何規(guī)避這些問(wèn)題呢,其實(shí)我的建議只有一點(diǎn),首先要明確理論,有了一定的理論做基礎(chǔ),然后就是不斷的實(shí)踐采坑,這樣才能明白某些問(wèn)題的點(diǎn)在哪里。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/76759.html
摘要:這兩種策略的區(qū)別就在于,公平策略會(huì)讓等待時(shí)間長(zhǎng)的線程優(yōu)先執(zhí)行,非公平策略則是等待時(shí)間長(zhǎng)的線程不一定會(huì)執(zhí)行,存在一個(gè)搶占資源的問(wèn)題。 之前有一篇文章我們簡(jiǎn)單的談到了Java中同步的問(wèn)題,但是可能在平常的開(kāi)發(fā)中,有些理論甚至是某些方式是用不到的,但是從程序的角度看,這些理論思想我們可以運(yùn)用到我們的開(kāi)發(fā)中,比如是不是應(yīng)該一談到同步問(wèn)題,就應(yīng)該想到用synchronized?,什么時(shí)候應(yīng)該用R...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問(wèn)到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過(guò)的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
摘要:作為面試官,我是如何甄別應(yīng)聘者的包裝程度語(yǔ)言和等其他語(yǔ)言的對(duì)比分析和主從復(fù)制的原理詳解和持久化的原理是什么面試中經(jīng)常被問(wèn)到的持久化與恢復(fù)實(shí)現(xiàn)故障恢復(fù)自動(dòng)化詳解哨兵技術(shù)查漏補(bǔ)缺最易錯(cuò)過(guò)的技術(shù)要點(diǎn)大掃盲意外宕機(jī)不難解決,但你真的懂?dāng)?shù)據(jù)恢復(fù)嗎每秒 作為面試官,我是如何甄別應(yīng)聘者的包裝程度Go語(yǔ)言和Java、python等其他語(yǔ)言的對(duì)比分析 Redis和MySQL Redis:主從復(fù)制的原理詳...
閱讀 3768·2021-08-30 09:47
閱讀 3690·2019-08-30 15:56
閱讀 677·2019-08-30 14:18
閱讀 698·2019-08-29 16:17
閱讀 2065·2019-08-29 11:07
閱讀 642·2019-08-26 13:53
閱讀 3443·2019-08-26 10:26
閱讀 2491·2019-08-23 18:30