亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java死鎖的產(chǎn)生原因及解決方法總結(jié)

 更新時(shí)間:2023年11月06日 09:24:22   作者:一一哥Sun  
Java中的死鎖是指多個(gè)線程同時(shí)占用一些共享資源且彼此相互等待,從而導(dǎo)致所有的線程都被阻塞,不能繼續(xù)執(zhí)行程序的情況,本文小編給大家介紹了Java死鎖的產(chǎn)生原因及解決方法總結(jié),需要的朋友可以參考下

一. 死鎖

1. 概念

Java中的死鎖是指多個(gè)線程同時(shí)占用一些共享資源且彼此相互等待,從而導(dǎo)致所有的線程都被阻塞,不能繼續(xù)執(zhí)行程序的情況。這就好比在一個(gè)十字路口,沒有交警也沒有紅綠燈指揮通行,所有的車輛都占據(jù)道路且互相等待對(duì)方讓出路權(quán),此時(shí)就很容易造成道路堵死,這其實(shí)就是道路的“死鎖”。如下圖所示:

2. 死鎖案例

雖然我們現(xiàn)在已經(jīng)知道了死鎖的概念,但具體什么時(shí)候會(huì)產(chǎn)生死鎖,相信很多小伙伴肯定還是弄不不清楚。所以接下來就給大家設(shè)計(jì)一個(gè)會(huì)產(chǎn)生死鎖的代碼案例,如下所示:

/**
 * @author 一一哥Sun
 * @company 千鋒教育
 */
public class Demo21 {
    // 定義2個(gè)鎖定的對(duì)象
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void method1() {
        // 鎖定對(duì)象1
        synchronized (lock1) {
            System.out.println("Method 1: 獲取對(duì)象lock1的鎖");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 鎖定對(duì)象2
            synchronized (lock2) {
                System.out.println("Method 1: 獲取對(duì)象lock2的鎖");
            }
        }
     }

    public void method2() {
        // 鎖定對(duì)象2
        synchronized (lock2) {
            System.out.println("Method 2: 獲取對(duì)象lock2的鎖");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            // 鎖定對(duì)象1
            synchronized (lock1) {
                System.out.println("Method 2: 獲取對(duì)象lock1的鎖");
            }
        }
    }

    public static void main(String[] args) {
        final Demo21 example = new Demo21();

        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                example.method1();
            }
        });

        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                example.method2();
            }
        });

        //開啟線程
        thread1.start();
        thread2.start();
    }
}

在上面的案例中,定義了兩個(gè)方法method1和method2,這兩個(gè)方法分別占用了lock1和lock2兩個(gè)鎖,并且在執(zhí)行過程中會(huì)互相等待對(duì)方的鎖,從而形成了死鎖。如果我們運(yùn)行該程序,就會(huì)看到兩個(gè)線程互相等待對(duì)方釋放自己占用的鎖,這最終會(huì)導(dǎo)致所有的線程都被阻塞。上述案例中死鎖的產(chǎn)生原因,如下圖所示:

根據(jù)上面的案例,你可以總結(jié)出會(huì)導(dǎo)致死鎖的條件嗎?我們繼續(xù)往下看。

3. 產(chǎn)生條件

其實(shí)一個(gè)Java程序要想產(chǎn)生死鎖,也并不是那么容易,只有同時(shí)滿足以下條件才行:

互斥條件:多個(gè)線程需同時(shí)訪問一個(gè)共享資源,但每次只能有一個(gè)線程訪問該資源;

請(qǐng)求和保持條件:一個(gè)線程在持有一個(gè)資源的同時(shí),還想請(qǐng)求另一個(gè)資源;

不可剝奪條件:已經(jīng)分配的資源不能被其他線程剝奪;

循環(huán)(環(huán)路)等待條件:多個(gè)線程形成了一個(gè)循環(huán)等待資源的鏈路,例如線程A等待線程B釋放自己所占用的資源,線程B等待線程C釋放自己所占用的資源,而線程C又等待線程A釋放自己所占用的資源。

只有同時(shí)滿足了以上條件,程序中才會(huì)產(chǎn)生死鎖。既然我們現(xiàn)在知道了死鎖的產(chǎn)生條件,那又該怎么解決呢?

4. 解決辦法

我們知道,當(dāng)出現(xiàn)死鎖時(shí),所有的線程都會(huì)被阻塞,且不能再繼續(xù)執(zhí)行程序,所以我們必須解決死鎖。一般情況下,我們可以通過以下方式來避免線程死鎖:

避免使用多個(gè)鎖;

盡可能減少同步代碼塊的長度;

嘗試改變鎖的獲取順序,避免線程之間形成循環(huán)等待;

使用定時(shí)鎖,當(dāng)?shù)却龝r(shí)間超過一定的時(shí)間值后就自動(dòng)釋放鎖。

以上就是打破死鎖條件的解決辦法,但是具體放到Java代碼中又是怎么樣的呢?接下來就把上面產(chǎn)生死鎖的代碼修改一下,解決死鎖問題。

5. 案例優(yōu)化

接下來就把上面產(chǎn)生死鎖的案例優(yōu)化一下,解決掉案例中的死鎖,代碼如下:

public class Demo22 {
    // 定義2個(gè)鎖定的對(duì)象
    private Object lock1 = new Object();
    private Object lock2 = new Object();

    public void method1() {
        //鎖定對(duì)象
        synchronized(lock1) {
            System.out.println("Method 1: 獲取對(duì)象鎖lock 1");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            synchronized(lock2) {
                System.out.println("Method 1: 獲取對(duì)象鎖lock 2");
            }
        }
    }

    public void method2() {
        synchronized(lock1) {
            System.out.println("Method 2: 獲取對(duì)象鎖lock 1");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            
            synchronized(lock2) {
                System.out.println("Method 2: 獲取對(duì)象鎖lock 2");
            }
        }
    }

    public static void main(String[] args) {
        final Demo22 demo = new Demo22();

        //定義兩個(gè)線程
        Thread thread1 = new Thread(new Runnable() {
        	@Override
            public void run() {
            	demo.method1();
            }
        });

        Thread thread2 = new Thread(new Runnable() {
        	@Override
            public void run() {
            	demo.method2();
            }
        });

        //開啟線程
        thread1.start();
        thread2.start();
    }
}

上面的這個(gè)案例與之前的案例代碼幾乎一樣,但與之不同的是,本案例中的方法method1和method2,都是先占用lock1鎖,再占用lock2鎖,這樣就避免了死鎖的發(fā)生,因?yàn)檫@兩個(gè)方法占用鎖的順序是一致的。所以我們?cè)诰帉懚嗑€程代碼時(shí),需要特別注意線程死鎖的問題,避免影響程序的正常執(zhí)行。

二. 結(jié)語

至此,小編就把Java中的死鎖給大家講解完畢了,現(xiàn)在你明白了嗎?我們?cè)诿嬖嚂r(shí)經(jīng)常會(huì)有面試官考察死鎖相關(guān)的內(nèi)容,比如死鎖是怎么產(chǎn)生的?如何避免死鎖?所以今天的內(nèi)容很重要,請(qǐng)各位一定要牢牢掌握哦。

以上就是Java死鎖的產(chǎn)生原因及解決方法總結(jié)的詳細(xì)內(nèi)容,更多關(guān)于Java死鎖的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL和Java通用加密解密方式小結(jié)

    MySQL和Java通用加密解密方式小結(jié)

    這篇文章主要介紹了MySQL和Java通用加密解密方式,加密方式使用AES加密,在轉(zhuǎn)成Base64,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-12-12
  • java圖形驗(yàn)證碼生成工具類 web頁面校驗(yàn)驗(yàn)證碼

    java圖形驗(yàn)證碼生成工具類 web頁面校驗(yàn)驗(yàn)證碼

    這篇文章主要為大家詳細(xì)介紹了java圖形驗(yàn)證碼生成工具類,web頁面校驗(yàn)驗(yàn)證碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-03-03
  • Spring實(shí)例化bean的方式代碼詳解

    Spring實(shí)例化bean的方式代碼詳解

    這篇文章主要介紹了Spring實(shí)例化bean的方式代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • 有關(guān)tomcat內(nèi)存溢出的完美解決方法

    有關(guān)tomcat內(nèi)存溢出的完美解決方法

    下面小編就為大家?guī)硪黄嘘P(guān)tomcat內(nèi)存溢出的完美解決方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-05-05
  • Java超細(xì)致講解數(shù)組的使用

    Java超細(xì)致講解數(shù)組的使用

    數(shù)組對(duì)于每一門編程語言來說都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java?語言中提供的數(shù)組是用來存儲(chǔ)固定大小的同類型元素
    2022-05-05
  • Java中Map接口使用以及有關(guān)集合的面試知識(shí)點(diǎn)匯總

    Java中Map接口使用以及有關(guān)集合的面試知識(shí)點(diǎn)匯總

    在java面試過程中,Map時(shí)常會(huì)被作為一個(gè)面試點(diǎn)來問,下面這篇文章主要給大家介紹了關(guān)于Java中Map接口使用以及有關(guān)集合的面試知識(shí)點(diǎn)匯總的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Spring Boot 配置文件詳解(小結(jié))

    Spring Boot 配置文件詳解(小結(jié))

    Spring Boot提供了兩種常用的配置文件,分別是properties文件和yml文件。本章重點(diǎn)介紹yml的語法和從配置文件中取值。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-04-04
  • Java動(dòng)態(tài)代理四種實(shí)現(xiàn)方式詳解

    Java動(dòng)態(tài)代理四種實(shí)現(xiàn)方式詳解

    這篇文章主要介紹了Java四種動(dòng)態(tài)代理實(shí)現(xiàn)方式,對(duì)于開始學(xué)習(xí)java動(dòng)態(tài)代理或者要復(fù)習(xí)java動(dòng)態(tài)代理的朋友來講很有參考價(jià)值,有感興趣的朋友可以參考一下
    2021-04-04
  • java 獲取當(dāng)前時(shí)間的三種方法

    java 獲取當(dāng)前時(shí)間的三種方法

    這篇文章主要介紹了java 獲取當(dāng)前時(shí)間的三種方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Spring 4.1+JSONP的使用指南

    Spring 4.1+JSONP的使用指南

    在解釋JSONP之前,我們需要了解下”同源策略“,這對(duì)理解跨域有幫助。基于安全的原因,瀏覽器是存在同源策略機(jī)制的,同源策略阻止從一個(gè)源加載的文檔或腳本獲取或設(shè)置另一個(gè)源加載額文檔的屬性。說的簡單點(diǎn)就是瀏覽器限制腳本只能和同協(xié)議、同域名、同端口的腳本進(jìn)行交互。
    2016-04-04

最新評(píng)論