国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

java并發(fā)-Semaphore

這篇具有很好參考價(jià)值的文章主要介紹了java并發(fā)-Semaphore。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

當(dāng)下Java并發(fā)編程日益普及,而Semaphore是Java提供的一種功能強(qiáng)大的線程同步工具,可用于控制同時(shí)訪問系統(tǒng)資源的線程數(shù)量。本篇博客將從Semaphore的簡介、底層實(shí)現(xiàn)和應(yīng)用場景等角度,深入探討Semaphore的原理以及其實(shí)現(xiàn)和使用方法。

## 1、Semaphore的簡介
Semaphore是一種計(jì)數(shù)器,用于控制同時(shí)訪問資源的線程數(shù)量。它通過一個(gè)計(jì)數(shù)器來表達(dá)可用資源的數(shù)量,當(dāng)有新線程需要訪問該資源時(shí),會(huì)先進(jìn)行請求,然后進(jìn)行P(proberen)操作,如果此時(shí)計(jì)數(shù)器的值為0,則線程就會(huì)被阻塞并進(jìn)入等待隊(duì)列中,等到其他線程釋放資源后才重新獲得控制權(quán)。而當(dāng)線程釋放資源時(shí),則會(huì)進(jìn)行V(verhogen)操作,將計(jì)數(shù)器的值加1,以通知其他線程可以繼續(xù)請求訪問資源。

Semaphore的構(gòu)造方法有兩個(gè)參數(shù),分別表示初始的資源數(shù)量和是否為公平鎖。如果將公平鎖設(shè)置為true,則多個(gè)線程并發(fā)訪問Semaphore時(shí),會(huì)按照它們的請求順序進(jìn)行處理,即先請求的線程也會(huì)先獲得資源。

Semaphore是一個(gè)典型的Java并發(fā)庫類,位于java.util.concurrent包中。

## 2、Semaphore的底層實(shí)現(xiàn)
在Semaphore的底層實(shí)現(xiàn)中,它是基于AQS(AbstractQueuedSynchronizer)的同步器實(shí)現(xiàn)的。AQS是一個(gè)為JDK提供的一個(gè)框架,用于實(shí)現(xiàn)同步器,比如鎖、Semaphore等,是基于隊(duì)列的鎖和同步器的實(shí)現(xiàn)框架。

Semaphore的底層實(shí)現(xiàn)主要基于兩個(gè)方法:
- acquire():申請?jiān)S可證,實(shí)際上就是P操作。
- release():釋放許可證,實(shí)際上就是V操作。

在Semaphore的實(shí)現(xiàn)中,如果許可證數(shù)量大于0,則線程可以直接獲取許可證資源并執(zhí)行任務(wù)。如果許可證數(shù)量小于等于0,則線程會(huì)被阻塞,直到其他線程釋放許可證資源,則當(dāng)前線程才能重新獲取許可證并執(zhí)行任務(wù)。需要注意的是,一旦線程獲取到許可證資源,則許可證數(shù)量就會(huì)減1。同理,每次釋放許可證資源,許可證數(shù)量就會(huì)加1。

## 3、Semaphore的應(yīng)用場景
Semaphore的應(yīng)用場景較為廣泛,主要用于控制并發(fā)數(shù)量,防止線程阻塞和死鎖等問題。下面列舉一些Semaphore的應(yīng)用場景和示例代碼:

### 場景1:限流器
Semaphore可用于實(shí)現(xiàn)限流器,即限制同時(shí)訪問某個(gè)資源的線程數(shù)量。比如,我們可以使用Semaphore控制某個(gè)接口的并發(fā)數(shù)量,防止服務(wù)被過度訪問而崩潰。下面是示例代碼:

```
public class RateLimit {
? private Semaphore semaphore;

? public RateLimit(int permits) {
? ? this.semaphore = new Semaphore(permits);
? }

? public void acquire() {
? ? semaphore.acquire();
? }

? public void release() {
? ? semaphore.release();
? }
}
```

### 場景2:數(shù)據(jù)庫連接池
Semaphore可用于實(shí)現(xiàn)數(shù)據(jù)庫連接池,即限制同時(shí)連接數(shù)據(jù)庫的線程數(shù)量。比如,我們可以使用Semaphore來限制連接數(shù),防止數(shù)據(jù)庫過度加載而崩潰。下面是示例代碼:

```
public class DBConnectionPool {
? private final Semaphore semaphore;
? private final List<Connection> pool;

? public DBConnectionPool(int permits, List<Connection> pool) {
? ? this.semaphore = new Semaphore(permits, true);
? ? this.pool = pool;
? }

? public Connection acquire() throws InterruptedException {
? ? semaphore.acquire();
? ? return pool.remove(0);
? }

? public void release(Connection conn) {
? ? pool.add(conn);
? ? semaphore.release();
? }
}
```

### 場景3:線程池
Semaphore可用于實(shí)現(xiàn)線程池,即限制同時(shí)執(zhí)行任務(wù)的線程數(shù)量。比如,我們可以使用Semaphore來控制線程池的大小,防止同時(shí)執(zhí)行太多的任務(wù)而導(dǎo)致系統(tǒng)崩潰。下面是示例代碼:

```
public class MyThreadPool {
? private final Semaphore semaphore;
? private final ExecutorService executor;

? public MyThreadPool(int permits, ExecutorService executor) {
? ? this.semaphore = new Semaphore(permits);
? ? this.executor = executor;
? }

? public void execute(Runnable task) throws InterruptedException {
? ? semaphore.acquire();
? ? executor.execute(() -> {
? ? ? try {
? ? ? ? task.run();
? ? ? } finally {
? ? ? ? semaphore.release();
? ? ? }
? ? });
? }
}
```

## 4、Semaphore的示例代碼
下面給出一個(gè)基于Semaphore實(shí)現(xiàn)的生產(chǎn)者-消費(fèi)者模型的示例代碼,具體實(shí)現(xiàn)可以參考如下:

```
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.Semaphore;

class QueueBuffer<T> {
? Queue<T> buffer = new LinkedList<>();
? Semaphore producerSemaphore = new Semaphore(1);
? Semaphore consumerSemaphore = new Semaphore(0);
? int maxBufferSize = 10;

? public void put(T obj) throws InterruptedException {
? ? producerSemaphore.acquire();
? ? try {
? ? ? while (buffer.size() == maxBufferSize) {
? ? ? ? consumerSemaphore.release();
? ? ? ? producerSemaphore.acquire();
? ? ? }
? ? ? buffer.add(obj);
? ? ? System.out.println(Thread.currentThread().getName() + " put: " + obj);
? ? ? consumerSemaphore.release();
? ? } finally {
? ? ? producerSemaphore.release();
? ? }
? }

? public T get() throws InterruptedException {
? ? consumerSemaphore.acquire();
? ? try {
? ? ? while (buffer.isEmpty()) {
? ? ? ? producerSemaphore.release();
? ? ? ? consumerSemaphore.acquire();
? ? ? }
? ? ? T obj = buffer.poll();
? ? ? System.out.println(Thread.currentThread().getName() + " get: " + obj);
? ? ? producerSemaphore.release();
? ? ? return obj;
? ? } finally {
? ? ? consumerSemaphore.release();
? ? }
? }
}

public class ProducerConsumer {
? public static void main(String[] args) throws InterruptedException {
? ? QueueBuffer<Integer> buffer = new QueueBuffer<>();
? ? Thread producer1 = new Thread(() -> {
? ? ? try {
? ? ? ? for (int i = 1; i <= 10; i++) {
? ? ? ? ? buffer.put(i);
? ? ? ? ? Thread.sleep(1000);
? ? ? ? }
? ? ? } catch (InterruptedException e) {
? ? ? ? e.printStackTrace();
? ? ? }
? ? }, "Producer1");

? ? Thread producer2 = new Thread(() -> {
? ? ? try {
? ? ? ? for (int i = 11; i <= 20; i++) {
? ? ? ? ? buffer.put(i);
? ? ? ? ? Thread.sleep(1000);
? ? ? ? }
? ? ? } catch (InterruptedException e) {
? ? ? ? e.printStackTrace();
? ? ? }
? ? }, "Producer2");

? ? Thread consumer1 = new Thread(() -> {
? ? ? try {
? ? ? ? for (int i = 1; i <= 5; i++) {
? ? ? ? ? buffer.get();
? ? ? ? ? Thread.sleep(2000);
? ? ? ? }
? ? ? } catch (InterruptedException e) {
? ? ? ? e.printStackTrace();
? ? ? }
? ? }, "Consumer1");

? ? Thread consumer2 = new Thread(() -> {
? ? ? try {
? ? ? ? for (int i = 6; i <= 10; i++) {
? ? ? ? ? buffer.get();
? ? ? ? ? Thread.sleep(2000);
? ? ? ? }
? ? ? } catch (InterruptedException e) {
? ? ? ? e.printStackTrace();
? ? ? }
? ? }, "Consumer2");

? ? producer1.start();
? ? producer2.start();
? ? consumer1.start();
? ? consumer2.start();

? ? producer1.join();
? ? producer2.join();
? ? consumer1.join();
? ? consumer2.join();
? }
}
```

以上代碼基于Semaphore實(shí)現(xiàn)了一個(gè)生產(chǎn)者-消費(fèi)者模型,并且內(nèi)置了兩個(gè)生產(chǎn)者和兩個(gè)消費(fèi)者線程,其中生產(chǎn)者會(huì)生產(chǎn)1-20的數(shù)字,并將其放入緩沖區(qū)中,而消費(fèi)者會(huì)從緩沖區(qū)中取出數(shù)據(jù)并進(jìn)行處理(這里采用簡單的輸出操作)。而Semaphore則用于控制兩個(gè)生產(chǎn)者之間的并發(fā)數(shù)量和兩個(gè)消費(fèi)者之間的并發(fā)數(shù)量,以確保線程安全性和程序的正確性。

## 結(jié)語
Semaphore是Java中一個(gè)非常實(shí)用的線程同步工具,可以幫助開發(fā)者控制并發(fā)訪問數(shù)量、防止線程阻塞和死鎖等問題,在多種場景下都有著廣泛的應(yīng)用。本文中介紹了Semaphore的簡介、底層實(shí)現(xiàn)和應(yīng)用場景,同時(shí)演示了Semaphore在生產(chǎn)消費(fèi)模型中的實(shí)現(xiàn)方式,相信讀者可以通過本文進(jìn)一步熟悉Semaphore的使用方法,從而提高對Java并發(fā)編程的理解和實(shí)踐能力。文章來源地址http://www.zghlxwxcb.cn/news/detail-451099.html

到了這里,關(guān)于java并發(fā)-Semaphore的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Java并發(fā)編程面試題

    Java并發(fā)編程面試題

    目錄 一、線程、進(jìn)程、程序 二、線程狀態(tài) ?三、線程的七大參數(shù) 四、線程有什么優(yōu)缺點(diǎn)? 五、start 和 run 方法有什么區(qū)別? 六、wait 和 sleep的區(qū)別? 七、lock與synchronized的區(qū)別 八、Volatile是線程安全的嗎?底層原理是什么? 九、synchronized作用和底層原理? 十一、Thre

    2024年02月12日
    瀏覽(25)
  • Java并發(fā)編程-volatile

    volatile 是 java 虛擬機(jī)提供的一種輕量級(jí)的同步機(jī)制,它有三個(gè)重要的特性: 保證可見性 不保證原子性 禁止指令重排 要理解這三個(gè)特性,就需要對 JMM (JAVA內(nèi)存模型)有一定的了解才行。 主要解決的問題: JVM中,每個(gè)線程都會(huì)存在本地內(nèi)存,本地內(nèi)存是公共內(nèi)存的副本,各

    2024年02月06日
    瀏覽(22)
  • 【java】開發(fā)——《并發(fā)編程》

    【java】開發(fā)——《并發(fā)編程》

    目錄 一.jmm 二.并發(fā)了什么 1.只有一個(gè)核(單核)并發(fā)還有沒有意義 2.單核,還有什么可見性問題 3.并發(fā)和并行 三.volitaile 1.變量的可見性問題 2.原因是什么 3.本次修改的變量直接刷到主內(nèi)存 4.聲明其他內(nèi)存對于這個(gè)地址的緩存無效 四.happens-befo 1.順序性問題 五.volitaile+cas 1.原

    2024年02月22日
    瀏覽(26)
  • Java并發(fā)編程實(shí)戰(zhàn)

    2023年06月19日
    瀏覽(20)
  • Java并發(fā)編程詳解:實(shí)現(xiàn)高效并發(fā)應(yīng)用的關(guān)鍵技術(shù)

    在當(dāng)前的計(jì)算機(jī)領(lǐng)域,高效的并發(fā)編程對于Java開發(fā)人員而言變得越發(fā)重要。作為流行的編程語言,Java提供了強(qiáng)大的并發(fā)編程支持,使開發(fā)人員能夠充分發(fā)揮多核處理器和線程的潛力,構(gòu)建高性能、高吞吐量的應(yīng)用程序。本文將深入探討Java并發(fā)編程的關(guān)鍵技術(shù),包括線程安全

    2024年02月13日
    瀏覽(30)
  • 【并發(fā)編程】深入理解Java并發(fā)之synchronized實(shí)現(xiàn)原理

    【并發(fā)編程】深入理解Java并發(fā)之synchronized實(shí)現(xiàn)原理

    分析: 通過 new MyThread() 創(chuàng)建了一個(gè)對象 myThread ,這時(shí)候堆中就存在了共享資源 myThread ,然后對 myThread 對象創(chuàng)建兩個(gè)線程,那么thread1線程和thread2線程就會(huì)共享 myThread 。 thread1.start() 和 thead2.start() 開啟了兩個(gè)線程,CPU會(huì)隨機(jī)調(diào)度這兩個(gè)線程。假如 thread1 先獲得 synchronized 鎖,

    2024年02月04日
    瀏覽(27)
  • java并發(fā)編程 LinkedBlockingDeque詳解

    java 并發(fā)編程系列文章目錄 首先queue是一種數(shù)據(jù)結(jié)構(gòu),一個(gè)集合中,先進(jìn)后出,有兩種實(shí)現(xiàn)的方式,數(shù)組和鏈表。從尾部追加,從頭部獲取。Deque是兩端都可以添加,且兩端都可以獲取,所以它的方法會(huì)有一系列的Last,F(xiàn)rist語義,添加或獲取等操作會(huì)指明哪個(gè)方向的,這也是

    2024年02月10日
    瀏覽(21)
  • 01.java并發(fā)編程面試寶典

    談?wù)勈裁词蔷€程池 線程池和數(shù)據(jù)庫連接池非常類似,可以統(tǒng)一管理和維護(hù)線程,減少?zèng)]有必要的開銷。 因?yàn)轭l繁的開啟線程或者停止線程,線程需要從新被 cpu 從就緒到運(yùn)行狀態(tài)調(diào)度,需要發(fā)生上下文切換 實(shí)際開發(fā)項(xiàng)目中 禁止自己 new 線程。必須使用線程池來維護(hù)和創(chuàng)建線

    2024年02月03日
    瀏覽(44)
  • 【面試】java并發(fā)編程面試題

    【面試】java并發(fā)編程面試題

    java并發(fā)面試題 https://javaguide.cn/home.html java基礎(chǔ)面試題 https://blog.csdn.net/jackfrued/article/details/44921941 java集合面試題 https://javaguide.cn/java/collection/java-collection-questions-01.html javaIO面試題 https://javaguide.cn/java/io/io-basis.html JVM面試題 https://javaguide.cn/java/jvm/jvm-garbage-collection.html 計(jì)算機(jī)網(wǎng)絡(luò)

    2024年01月21日
    瀏覽(38)
  • java并發(fā)編程:ArrayBlockingQueue詳解

    java并發(fā)編程:ArrayBlockingQueue詳解

    ArrayBlockingQueue 顧名思義:基于數(shù)組的阻塞隊(duì)列。數(shù)組是要指定長度的,所以使用 ArrayBlockingQueue 時(shí)必須指定長度,也就是它是一個(gè)有界隊(duì)列。它實(shí)現(xiàn)了 BlockingQueue 接口,有著隊(duì)列、集合以及阻塞隊(duì)列的所有方法。 ArrayBlockingQueue 是線程安全的,內(nèi)部使用 ReentrantLock 來保證。A

    2024年02月08日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包