亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java基礎:一個100%會發生死鎖的程序

發布時間:2020-07-20 20:54:11 來源:網絡 閱讀:357 作者:沙漏半杯 欄目:編程語言

?多線程是Java工程師進階所必須掌握的一項技能,也是面試中繞不過的一個環節,而死鎖又是多線程同步失敗的經典案例,對于復雜的系統,死鎖是很難通過代碼層面來做靜態檢測和排查的,所以有的面試官會從反向出發,讓你手寫一個死鎖程序。
????先來看一個網絡上常見的死鎖程序(可能存在問題):

public?class?DeadLockTest?{????private?static?Object?lock1?=?new?Object();????private?static?Object?lock2?=?new?Object();????public?static?void?main(String[]?args)?{????????new?Thread(()?->?{
????????????synchronized?(lock1)?{
????????????????System.out.println("thread1?acquired?lock1");????????????????try?{
????????????????????Thread.sleep(1000);
????????????????}?catch?(InterruptedException?e)?{
????????????????????e.printStackTrace();
????????????????}
????????????????System.out.println("thread1?try?to?acquire?lock2");
????????????????synchronized?(lock2)?{
????????????????????System.out.println("thread1?acquired?lock2");
????????????????}
????????????}
????????},?"t1").start();????????new?Thread(()?->?{
????????????synchronized?(lock2)?{
????????????????System.out.println("thread2?acquired?lock2");????????????????try?{
????????????????????Thread.sleep(1000);
????????????????}?catch?(InterruptedException?e)?{
????????????????????e.printStackTrace();
????????????????}
????????????????System.out.println("thread2?try?to?acquire?lock1");
????????????????synchronized?(lock1)?{
????????????????????System.out.println("thread2?acquired?lock1");
????????????????}
????????????}
????????},?"t2").start();????????
????????//?檢測死鎖
????????checkDeadLock();
????????System.out.println("main?thread?end");
????}????public?static?void?checkDeadLock()?{
????????ThreadMXBean?mxBean?=?ManagementFactory.getThreadMXBean();
????????ScheduledExecutorService?scheduled?=?Executors.newScheduledThreadPool(1);????????//?初始等待5秒,每隔10秒檢測一次
????????scheduled.scheduleAtFixedRate(()->{????????????long[]?threadIds?=?mxBean.findDeadlockedThreads();????????????if?(threadIds?!=?null)?{
????????????????System.out.println("檢測到死鎖線程:");
????????????????ThreadInfo[]?threadInfos?=?mxBean.getThreadInfo(threadIds);????????????????for?(ThreadInfo?info?:?threadInfos)?{
????????????????????System.out.println(info.getThreadId()?+?":"?+?info.getThreadName());
????????????????}
????????????}
????????},?5L,?10L,?TimeUnit.SECONDS);
????}
}

????上面這段程序在99.99%的情況下都會發生死鎖,但是從理論的角度來講,死鎖并不是100%會發生的,比如:線程t1先啟動并獲取了鎖lock1,在休眠的這1s的過程中,JVM并未發生線程調度(實際上基本不可能),t2未得到執行也未獲取到鎖lock2,這時候t1休眠結束繼續執行并獲取了鎖lock2,那么這種情況下就不會發生死鎖了。
????如何寫一個100%會發生死鎖的程序呢?直接上代碼:

public?class?DeadLockTest?{????private?static?Object?lock1?=?new?Object();????private?static?Object?lock2?=?new?Object();????//?這里的flag需要用volatile修飾,以保證線程間的可見性
????private?static?volatile?boolean?flag1?=?false;????private?static?volatile?boolean?flag2?=?false;????public?static?void?main(String[]?args)?{????????new?Thread(()?->?{
????????????synchronized?(lock1)?{
????????????????flag1?=?true;
????????????????System.out.println("thread1?acquired?lock1");????????????????while?(!flag2)?{????????????????????//?無限循環,等待thread2獲取到lock2后再繼續往下執行(相比使用Thread.sleep(1000)在理論上是100%會出現死鎖)
????????????????????Thread.yield();
????????????????}
????????????????System.out.println("thread1?try?to?acquire?lock2");
????????????????synchronized?(lock2)?{
????????????????????System.out.println("thread1?acquired?lock2");
????????????????}
????????????}
????????},?"t1").start();????????new?Thread(()?->?{
????????????synchronized?(lock2)?{
????????????????flag2?=?true;
????????????????System.out.println("thread2?acquired?lock2");????????????????while?(!flag1)?{
????????????????????Thread.yield();
????????????????}
????????????????System.out.println("thread2?try?to?acquire?lock1");
????????????????synchronized?(lock1)?{
????????????????????System.out.println("thread2?acquired?lock1");
????????????????}
????????????}
????????},?"t2").start();????????//?檢測死鎖
????????checkDeadLock();
????????System.out.println("main?thread?end");
????}????public?static?void?checkDeadLock()?{
????????ThreadMXBean?mxBean?=?ManagementFactory.getThreadMXBean();
????????ScheduledExecutorService?scheduled?=?Executors.newScheduledThreadPool(1);????????//?初始等待5秒,每隔10秒檢測一次
????????scheduled.scheduleAtFixedRate(()?->?{????????????long[]?threadIds?=?mxBean.findDeadlockedThreads();????????????if?(threadIds?!=?null)?{
????????????????System.out.println("檢測到死鎖線程:");
????????????????ThreadInfo[]?threadInfos?=?mxBean.getThreadInfo(threadIds);????????????????for?(ThreadInfo?info?:?threadInfos)?{
????????????????????System.out.println(info.getThreadId()?+?":"?+?info.getThreadName());
????????????????}
????????????}
????????},?5L,?10L,?TimeUnit.SECONDS);
????}
}


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

济阳县| 格尔木市| 凤台县| 靖远县| 新乡县| 兴宁市| 平顶山市| 广饶县| 永康市| 临颍县| 克什克腾旗| 新乡市| 舒兰市| 永寿县| 伊春市| 富平县| 绥芬河市| 改则县| 桦甸市| 托克逊县| 高青县| 晋宁县| 辽宁省| 宜黄县| 六盘水市| 长子县| 六安市| 库尔勒市| 永宁县| 乌拉特中旗| 长顺县| 抚州市| 虞城县| 镇赉县| 辰溪县| 湖州市| 桐城市| 南皮县| 桃园县| 北碚区| 石楼县|