成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java并發(fā)編程:線程活躍性問題:死鎖、活鎖與饑餓

開發(fā) 前端
活躍性問題意味著程序永遠(yuǎn)無法得到運行的最終結(jié)果。與之前提到的線程安全問題導(dǎo)致的程序錯誤相比,活躍性問題的后果可能更嚴(yán)重。例如,若發(fā)生死鎖,程序會完全卡死無法運行。

活躍性問題意味著程序永遠(yuǎn)無法得到運行的最終結(jié)果。與之前提到的線程安全問題導(dǎo)致的程序錯誤相比,活躍性問題的后果可能更嚴(yán)重。例如,若發(fā)生死鎖,程序會完全卡死無法運行。

最典型的三種活躍性問題是死鎖(Deadlock)、活鎖(Livelock)和饑餓(Starvation)。下面逐一介紹。

1. 死鎖(Deadlock)

最常見的活躍性問題是死鎖。當(dāng)兩個線程互相等待對方持有的資源,且都不釋放自己已持有的資源時,就會導(dǎo)致永久阻塞。

代碼示例:

public class DeadLock {

    static Object lock1 = new Object();
    static Object lock2 = new Object();

    public static void main(String[] args) {

        new Thread(() -> {
            try {
                synchronized (lock1) {
                    Thread.sleep(500);
                    synchronized (lock2) {
                        System.out.println("Thread 1 成功執(zhí)行");
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                synchronized (lock2) {
                    Thread.sleep(500);
                    synchronized (lock1) {
                        System.out.println("Thread 2 成功執(zhí)行");
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

輸出結(jié)果:

Acquired lock1, trying to acquire lock2.  
Acquired lock2, trying to acquire lock1.

啟動程序后會發(fā)現(xiàn),程序一直在運行,但永遠(yuǎn)無法輸出線程 1 和線程 2 的執(zhí)行結(jié)果,說明兩者都被卡住了。如果不強制終止進(jìn)程,它們將永遠(yuǎn)等待。

注意:后續(xù)章節(jié)會詳細(xì)講解synchronized關(guān)鍵字,目前只需知道它能確保同一時刻最多一個線程執(zhí)行代碼(需持有對應(yīng)鎖),以控制并發(fā)安全。

死鎖的必要條件

根據(jù)上述示例,可以分析死鎖發(fā)生的四個必要條件:

  • 互斥條件:資源一次只能被一個進(jìn)程或線程使用。例如,鎖被某個線程持有后,其他線程無法獲取,直到釋放。
  • 請求與保持條件:線程在持有第一個鎖的同時請求第二個鎖。例如,線程 1 持有鎖 A 后嘗試獲取鎖 B,且不釋放鎖 A。
  • 不可剝奪條件:鎖不會被外部強制剝奪。即沒有外界干預(yù)來終止死鎖。
  • 循環(huán)等待條件:多個線程形成環(huán)形等待鏈。例如,線程 A 等線程 B 釋放資源,線程 B 等線程 A 釋放資源;或多個線程形成 A→B→C→A 的循環(huán)等待鏈。

??以上四個條件缺一不可!只要破壞任意一個條件,即可避免死鎖!

如何預(yù)防死鎖

如果線程一次只能獲取一個鎖,則不會發(fā)生死鎖。雖然不太實用,但這是最徹底的解決方案。

以下是兩種常用預(yù)防方法:

  • 按固定順序獲取鎖
    如果必須獲取多個鎖,設(shè)計時需要確保所有線程按相同順序獲取鎖。例如修改上述代碼:
// 線程 1 和線程 2 均按 lock1 → lock2 順序獲取
Thread1--> 獲取lock1--> 獲取lock2--> 執(zhí)行成功;
Thread2--> 獲取lock1--> 獲取lock2--> 執(zhí)行成功;
  • 超時放棄
    使用synchronized內(nèi)置鎖時,線程會無限等待。而Lock接口的tryLock(long time, TimeUnit unit)方法允許設(shè)置等待時間。若超時未獲鎖,線程可主動釋放已持有的鎖,從而避免死鎖。

2. 活鎖(Livelock)

什么是活鎖

活鎖是第二種活躍性問題。與死鎖類似,程序無法得到最終結(jié)果,但線程并非完全阻塞,而是不斷嘗試執(zhí)行卻無法推進(jìn)。

例如:兩人迎面相遇,互相讓路,結(jié)果你往右我往左,再次相撞,最終誰也無法通過。

代碼示例:

public class Livelock {

    private Lock lock1 = new ReentrantLock(true);
    private Lock lock2 = new ReentrantLock(true);

    public static void main(String[] args) {
        Livelock livelock = new Livelock();
        new Thread(livelock::operation1, "T1").start();
        new Thread(livelock::operation2, "T2").start();
    }

    public void operation1() {
        while (true) {
            lock1.tryLock();
            System.out.println("獲取 lock1,嘗試獲取 lock2");
            sleep(50);  // 模擬業(yè)務(wù)耗時

            if (lock2.tryLock()) {
                System.out.println("獲取 lock2");
            } else {
                System.out.println("無法獲取 lock2,釋放 lock1");
                lock1.unlock();
                continue;
            }

            System.out.println("執(zhí)行 operation1");
            break;
        }
        lock2.unlock();
        lock1.unlock();
    }

    public void operation2() {
        while (true) {
            lock2.tryLock();
            System.out.println("獲取 lock2,嘗試獲取 lock1");
            sleep(50);

            if (lock1.tryLock()) {
                System.out.println("獲取 lock1");
            } else {
                System.out.println("無法獲取 lock1,釋放 lock2");
                lock2.unlock();
                continue;
            }

            System.out.println("執(zhí)行 operation2");
            break;
        }
        lock1.unlock();
        lock2.unlock();
    }

    private void sleep(long sleepTime) {
        try {
            Thread.sleep(sleepTime);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

輸出結(jié)果:

獲取lock1,嘗試獲取lock2  
獲取lock2,嘗試獲取lock1  
無法獲取lock2,釋放lock1  
獲取lock2,嘗試獲取lock1  
無法獲取lock1,釋放lock2  
...(循環(huán))

從日志可見,兩個線程不斷獲取和釋放鎖,但都無法完成操作。

注意:由于線程調(diào)度,此示例可能在運行一段時間后自動解除活鎖,但不影響理解其原理。

如何預(yù)防活鎖

活鎖的根源在于線程同時釋放鎖并重試。解決方法是為鎖獲取設(shè)置隨機等待時間,打破同步釋放的節(jié)奏:

修改代碼:

// 在 sleep 方法中增加隨機等待時間
private void sleep(long sleepTime) {
    try {
        Thread.sleep(sleepTime + (long)(Math.random() * 100));
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

修改后運行結(jié)果:

獲取lock1,嘗試獲取lock2  
獲取lock2,嘗試獲取lock1  
無法獲取lock1,釋放lock2  
獲取lock2  
執(zhí)行operation1  
獲取lock2,嘗試獲取lock1  
獲取lock1  
執(zhí)行operation2

此時活鎖問題基本消失。

典型場景:消息隊列中某個錯誤消息反復(fù)重試,導(dǎo)致線程忙但無結(jié)果。解決方法:

  1. 將錯誤消息移至隊列尾部延遲處理;
  2. 限制重試次數(shù),超過后丟棄或特殊處理。

3. 饑餓(Starvation)

什么是饑餓

饑餓指線程長期無法獲取資源(如 CPU 時間),導(dǎo)致無法運行。常見場景:

  • 線程優(yōu)先級過低,長期得不到調(diào)度;
  • 某線程持有鎖且不釋放(如無限循環(huán)),其他線程長期等待。

饑餓的影響

導(dǎo)致程序響應(yīng)性差。例如,瀏覽器前端線程因后臺線程占用 CPU 無法響應(yīng)操作。

如何預(yù)防饑餓

  • 確保邏輯正確,及時釋放鎖;
  • 合理設(shè)置線程優(yōu)先級(或不設(shè)置優(yōu)先級)。
責(zé)任編輯:武曉燕 來源: 程序猿技術(shù)充電站
相關(guān)推薦

2023-06-29 08:18:27

Java顯示鎖顯示條件隊列

2021-03-26 10:40:16

MySQL鎖等待死鎖

2023-10-08 09:34:11

Java編程

2024-09-27 09:31:25

2024-02-26 08:33:51

并發(fā)編程活躍性安全性

2025-02-17 00:00:25

Java并發(fā)編程

2025-02-19 00:05:18

Java并發(fā)編程

2011-12-29 13:31:15

Java

2023-07-05 08:18:54

Atomic類樂觀鎖悲觀鎖

2009-06-17 11:23:00

Java多線程

2018-10-25 15:55:44

Java多線程鎖優(yōu)化

2019-04-12 15:14:44

Python線程

2020-07-06 08:03:32

Java悲觀鎖樂觀鎖

2022-07-10 20:49:57

javaVolatile線程

2010-05-24 14:04:48

JavaSwing多線程

2017-05-03 16:26:24

MySQL并發(fā)死鎖

2023-08-25 09:36:43

Java編程

2025-01-10 07:10:00

2025-02-06 03:14:38

2024-02-27 17:46:25

并發(fā)程序CPU
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 一级a爱片久久毛片 | 欧美色成人 | 超碰精品在线观看 | 91免费视频 | 中文字幕日韩一区 | 久热久| 中文二区 | 99re在线视频 | 日韩视频在线免费观看 | 久久精品欧美一区二区三区不卡 | 狠狠天天| 成人亚洲在线 | 久久久久久久久久久久亚洲 | 国产a视频| 亚洲一区免费视频 | 亚洲一区二区日韩 | 中文字幕在线一区二区三区 | 欧美激情在线精品一区二区三区 | 亚洲精品视频一区 | 99精品网| 一级黄色片一级黄色片 | 日本在线你懂的 | 99精品视频一区二区三区 | 国产精品国产成人国产三级 | 亚洲精品中文在线 | 成人深夜福利 | 国产乱码精品一品二品 | 九热在线 | 精品国产欧美一区二区三区成人 | 久久亚洲天堂 | 91亚洲精 | 精品国产乱码久久久久久蜜臀 | 亚洲福利 | 永久精品 | 欧美日韩不卡 | 精品精品 | 免费的黄色片子 | 狠狠婷婷综合久久久久久妖精 | 欧美日韩一区在线观看 | 欧美 中文字幕 | 中文字幕在线看第二 |