首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java 並發實戰:Semaphore 信號量控制資源訪問併發數

     編輯:Java 綜合教學

核心概念

Semaphore 維護一組虛擬許可證(計數器),acquire() 獲取許可(不足則阻塞),release() 釋放許可(喚醒等待執行緒)。常用於限流、資源池隔離、併發訪問控制。

構造函數與公平性

Semaphore(int permits, boolean fair)
  • permits:初始許可證數量(最大併發數)。
  • fair:true 使用公平鎖(FIFO),false 非公平(預設,吞吐較高)。

完整實戰代碼

package com.thread.test.thread;

import java.util.Random;
import java.util.concurrent.*;

public class MySemaphore {
    public static void main(String[] args) {
        // 5 個許可,公平模式
        Semaphore sp = new Semaphore(5, true);
        ExecutorService es = Executors.newCachedThreadPool();
        Random r = new Random();
        
        for (int i = 0; i < 10; i++) {
            // 隨機執行 0-9 秒,模擬不同業務耗時
            es.execute(new Needer(sp, r.nextInt(10), "needer-" + i));
        }
        es.shutdown();
    }
}

class Needer implements Runnable {
    private final Semaphore sp;
    private final int seconds;
    private final String neederName;

    Needer(Semaphore sp, int seconds, String neederName) {
        this.sp = sp;
        this.seconds = seconds;
        this.neederName = neederName;
    }

    @Override
    public void run() {
        try {
            sp.acquire(); // 獲取許可,阻塞直到可用
            System.out.println("Needer " + neederName + " begin, need time: " + seconds + "s");
            long start = System.currentTimeMillis();
            
            for (int i = 0; i < seconds; i++) {
                Thread.sleep(1000);
                System.out.println("Needer: " + neederName + " ============ " + i + " ============");
            }
            
            long duration = System.currentTimeMillis() - start;
            System.out.println("Needer " + neederName + " over, executing time: " 
                + TimeUnit.SECONDS.convert(duration, TimeUnit.MILLISECONDS) + "s");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            sp.release(); // 釋放許可,喚醒下一個等待者
        }
    }
}

執行效果說明

  • 同時只有 5 個 Needer 能進入關鍵區執行。
  • 其餘 5 個在 acquire() 處阻塞,按公平順序依次獲得許可。
  • finally 確保釋放許可,防止死鎖。

項目地址

https://github.com/windwant/threadtest

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved