成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

java多線程(5)死鎖

CoreDump / 2593人閱讀

摘要:如果線程已經(jīng)獲得鎖,還要獲得鎖,同時(shí)線程已經(jīng)獲得鎖,還要獲得鎖,那么線程和就會(huì)一直阻塞住。

上文講到synchronized關(guān)鍵字在多線程中的使用,既然用到了鎖,就會(huì)有出現(xiàn)死鎖的情況。一個(gè)線程獲得鎖,如果其他線程也想獲得同樣的鎖就會(huì)阻塞住,等待鎖的釋放。如果線程A已經(jīng)獲得鎖1,還要獲得鎖2,同時(shí)線程B已經(jīng)獲得鎖2,還要獲得鎖1,那么線程A和B就會(huì)一直阻塞住。

例子

依照慣例先舉個(gè)例子:

public class Test {

    
    
    public static void main(String[] args) throws InterruptedException {
        Object lock1 = new Object();
        Object lock2 = new Object();
        Thread t1 = new Thread(new Test().new Tt1(lock1, lock2));
        Thread t2 = new Thread(new Test().new Tt2(lock1, lock2));
        t1.start();
        t2.start();
    }
    
    
    class Tt1 implements Runnable{

        private Object lock1;
        private Object lock2;
        
        public Tt1(Object lock1,Object lock2) {
            this.lock1 = lock1;
            this.lock2 = lock2;
        }

        @Override
        public void run() {
            
            synchronized (lock1) {
                System.out.println(this.getClass()+"-------1");
                try {
                    Thread.sleep(1000);
                    synchronized (lock2) {
                        System.out.println(this.getClass()+"-------2");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class Tt2 implements Runnable{

        private Object lock1;
        private Object lock2;
        
        public Tt2(Object lock1,Object lock2) {
            this.lock1 = lock1;
            this.lock2 = lock2;
        }

        @Override
        public void run() {
            
            synchronized (lock2) {
                System.out.println(this.getClass()+"-------1");
                try {
                    Thread.sleep(1000);
                    synchronized (lock1) {
                        System.out.println(this.getClass()+"-------2");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

執(zhí)行結(jié)果:

class Test$Tt1-------1
class Test$Tt2-------1

2個(gè)線程都只執(zhí)行到了第一步,就沒有往下執(zhí)行,都處于了阻塞狀態(tài),這就是死鎖。

定位死鎖

死鎖問(wèn)題并不是一個(gè)容易被發(fā)現(xiàn)和定位的問(wèn)題,如果系統(tǒng)出現(xiàn)死鎖問(wèn)題,該如何定位?

1.使用jps,查詢java虛擬機(jī)的pid

2.使用jstack打印堆棧

以Thread-1為例介紹下每一部分的意思
1).Thread-1 線程名稱
2).prio=5 線程優(yōu)先級(jí)
3).os_prio=0 本地的優(yōu)先級(jí)
4).tid=0x000000001929b800 線程id
5).nid=0xfb34 本地的線程id
6)
java.lang.Thread.State: BLOCKED (on object monitor)
線程狀態(tài)處于阻塞
7) waiting to lock <0x00000000d5dd0c38> (a java.lang.Object)正在等待的鎖
8)locked <0x00000000d5dd0c48> (a java.lang.Object) 已獲取的鎖

現(xiàn)在我們可以看到Thread-1和Thread-0都處于阻塞狀態(tài),Thread-1獲取了‘0x00000000d5dd0c48’鎖,等待‘0x00000000d5dd0c38’鎖,而Thread-0則剛好相反。

避免死鎖

我們已經(jīng)知道了死鎖的形成和定位,再來(lái)講講如何避免:
1.盡量在線程中不嵌套獲取多個(gè)資源,但你只需獲取一個(gè)時(shí)就不會(huì)出現(xiàn)死鎖、
2.如果不得不嵌套使用時(shí),要多考慮嵌套的順序
3.死鎖是因?yàn)闊o(wú)限的阻塞等待,如果能有一個(gè)最大的等待時(shí)間就可以解決這個(gè)問(wèn)題。synchronized不具備這個(gè)功能,但是我們可以使用Lock類中的tryLock方法去嘗試獲取鎖,這個(gè)方法可以指定一個(gè)超時(shí)時(shí)限,在等待超過(guò)該時(shí)限之后返回失敗信息

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76377.html

相關(guān)文章

  • 【全棧之路】JAVA基礎(chǔ)課程三_線程死鎖(20190614v1.0)

    摘要:一個(gè)進(jìn)程可以有多個(gè)線程。線程又叫做輕量級(jí)進(jìn)程。這樣兩個(gè)進(jìn)程相互無(wú)休止地等待下去,均無(wú)法繼續(xù)執(zhí)行,此時(shí)兩個(gè)進(jìn)程陷入死鎖狀態(tài)。不剝奪條件進(jìn)程所獲得的資源在未使用完畢之前,不能被其他進(jìn)程強(qiáng)行奪走,即只能由獲得該資源的進(jìn)程自己來(lái)釋放只能是主動(dòng)釋放。 歡迎進(jìn)入JAVA基礎(chǔ)課程 博客地址:https://blog.csdn.net/houjiyu...本系列文章將主要針對(duì)JAVA一些基礎(chǔ)知識(shí)點(diǎn)進(jìn)...

    Allen 評(píng)論0 收藏0
  • 【全棧之路】JAVA基礎(chǔ)課程三_線程死鎖(20190614v1.0)

    摘要:一個(gè)進(jìn)程可以有多個(gè)線程。線程又叫做輕量級(jí)進(jìn)程。這樣兩個(gè)進(jìn)程相互無(wú)休止地等待下去,均無(wú)法繼續(xù)執(zhí)行,此時(shí)兩個(gè)進(jìn)程陷入死鎖狀態(tài)。不剝奪條件進(jìn)程所獲得的資源在未使用完畢之前,不能被其他進(jìn)程強(qiáng)行奪走,即只能由獲得該資源的進(jìn)程自己來(lái)釋放只能是主動(dòng)釋放。 歡迎進(jìn)入JAVA基礎(chǔ)課程 博客地址:https://blog.csdn.net/houjiyu...本系列文章將主要針對(duì)JAVA一些基礎(chǔ)知識(shí)點(diǎn)進(jìn)...

    warnerwu 評(píng)論0 收藏0
  • Java線程專題一:并發(fā)所面臨的問(wèn)題

    摘要:但是并不是什么多線程就可以隨便用,有的時(shí)候多線程反而會(huì)造成系統(tǒng)的負(fù)擔(dān),而且多線程還會(huì)造成其他的數(shù)據(jù)問(wèn)題,下面就來(lái)介紹一下多線程面臨的問(wèn)題。下面這張圖是多線程運(yùn)行時(shí)候的情況,我們發(fā)現(xiàn)上下文切換的次數(shù)暴增。 并發(fā)的概念: 在Java中是支持多線程的,多線程在有的時(shí)候可以大提高程序的速度,比如你的程序中有兩個(gè)完全不同的功能操作,你可以讓兩個(gè)不同的線程去各自執(zhí)行這兩個(gè)操作,互不影響,不需要執(zhí)行...

    madthumb 評(píng)論0 收藏0
  • java高并發(fā)系列 - 第1天:必須知道的幾個(gè)概念

    摘要:并發(fā)和并行并發(fā)和并行是兩個(gè)非常容易被混淆的概念。并發(fā)說(shuō)的是在一個(gè)時(shí)間段內(nèi),多件事情在這個(gè)時(shí)間段內(nèi)交替執(zhí)行。并行說(shuō)的是多件事情在同一個(gè)時(shí)刻同事發(fā)生。由于線程池是一個(gè)線程,得不到執(zhí)行,而被餓死,最終導(dǎo)致了程序死鎖的現(xiàn)象。 同步(Synchronous)和異步(Asynchronous) 同步和異步通常來(lái)形容一次方法調(diào)用,同步方法調(diào)用一旦開始,調(diào)用者必須等到方法調(diào)用返回后,才能繼續(xù)后續(xù)的行為...

    zhoutk 評(píng)論0 收藏0
  • 超詳細(xì)的Java面試題總結(jié)(二)之Java基礎(chǔ)知識(shí)篇

    摘要:超詳細(xì)的面試題總結(jié)一之基本知識(shí)多線程和虛擬機(jī)創(chuàng)建線程有幾種不同的方式你喜歡哪一種為什么繼承類實(shí)現(xiàn)接口應(yīng)用程序可以使用框架來(lái)創(chuàng)建線程池實(shí)現(xiàn)接口。死亡線程方法執(zhí)行結(jié)束,或者因異常退出了方法,則該線程結(jié)束生命周期。死亡的線程不可再次復(fù)生。 超詳細(xì)的Java面試題總結(jié)(一)之Java基本知識(shí) 多線程和Java虛擬機(jī) 創(chuàng)建線程有幾種不同的方式?你喜歡哪一種?為什么? 繼承Thread類 實(shí)現(xiàn)R...

    wangjuntytl 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<