R ggplot2 繪製 PCA 主成分分析圖,每個繪圖像素都自己掌控的感覺倍兒爽~ ...
轉自:
http://www.java265.com/JavaCourse/202204/3181.html
下文筆者講述Java中產生死鎖的方法分享,如下所示
死鎖的簡介
死鎖:
多個線程互相阻塞,
這裡面一個線程或多個線程等待某個資源被釋放,
此時就會造成線程被無限期地阻塞,程式無法正常終止
我們將這種現象稱之為“死鎖”
死鎖產生的四個必要條件
1.某些線程間資源互斥使用,當某個資源被一個線程使用(占有)時,其他某個(或多個)線程不能使用
2.不可搶占,資源請求者無法從別的線程中奪取資源
3.請求和保持,線程請求資源後,再請求其他資源時,還未對原資料放棄持有
4.迴圈等待,即存在一個等待隊列:P1占有P2的資源,P2占有P3的資源,P3占有P1的資源。這樣就形成了一個等待環路。
當以上四個條件都成立時,此時就會產生死鎖
例:
package com.java265.other; import java.util.Date; public class Test16 { public static String obj1 = "java265.com-1"; public static String obj2 = "java265.com-2"; public static void main(String[] args) { LockA a = new LockA(); new Thread(a).start(); LockB b = new LockB(); new Thread(b).start(); } } class LockA implements Runnable { public void run() { try { System.out.println(new Date().toString() + " LockA 開始執行"); while (true) { synchronized (Test16.obj1) { System.out.println(new Date().toString() + " LockA 鎖住 obj1"); Thread.sleep(3000); // 此處等待是給B能鎖住機會 synchronized (Test16.obj2) { System.out.println(new Date().toString() + " LockA 鎖住 obj2"); Thread.sleep(60 * 1000); // 為測試,占用了就不放 } } } } catch (Exception e) { e.printStackTrace(); } } } class LockB implements Runnable { public void run() { try { System.out.println(new Date().toString() + " LockB 開始執行"); while (true) { synchronized (Test16.obj2) { System.out.println(new Date().toString() + " LockB 鎖住 obj2"); Thread.sleep(3000); // 此處等待是給A能鎖住機會 synchronized (Test16.obj1) { System.out.println(new Date().toString() + " LockB 鎖住 obj1"); Thread.sleep(60 * 1000); // 為測試,占用了就不放 } } } } catch (Exception e) { e.printStackTrace(); } } } ------以上程式將產生死鎖------- Thu Apr 28 22:35:45 CST 2022 LockB 開始執行 Thu Apr 28 22:35:45 CST 2022 LockA 開始執行 Thu Apr 28 22:35:45 CST 2022 LockB 鎖住 obj2 Thu Apr 28 22:35:45 CST 2022 LockA 鎖住 obj1