国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

AQS同步組件--Semaphore

DobbyKim / 1611人閱讀

摘要:演示代碼獲取一個許可釋放一個許可我們在執(zhí)行方式前后包裹上和,這樣其實我們就相當(dāng)于一個單線程在執(zhí)行。嘗試獲取一個許可釋放一個許可這次我們使用的是一個方法,這個方法的第一個參數(shù)是表示等待毫秒,第二參數(shù)是表示多長時間嘗試一次,表示毫秒。

Semaphore
什么是Semaphore?
是用于控制某個資源同一時間被線程訪問的個數(shù),提供acquire()和release()方法,acquire獲取一個許可,如果沒有獲取的到就等待,release是在操作完成后釋放一個許可,Semaphore維護(hù)了當(dāng)前訪問的個數(shù),通過同步機制來控制同時訪問的個數(shù),在數(shù)據(jù)結(jié)構(gòu)里鏈表中的節(jié)點是可以無限個的,而Semaphore里維護(hù)的是一個有大小的限鏈表。
Semaphore的使用場景
Semaphore用于僅能提供有限訪問的資源,比如數(shù)據(jù)庫中的鏈接數(shù)只有20但是我們上層應(yīng)用數(shù)可能遠(yuǎn)大于20,如果同時都對數(shù)據(jù)庫鏈接進(jìn)行獲取,那很定會因為鏈接獲取不到而報錯,所以我們就要對數(shù)據(jù)庫鏈接的訪問進(jìn)行控制。
演示代碼
@Slf4j
public class SemaphoreExample1 {

    private final static int threadCount = 20;

    public static void main(String[] args) throws Exception {

        ExecutorService exec = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < threadCount; i++) {
            final int threadNum = i;
            exec.execute(() -> {
                try {
                    semaphore.acquire(); // 獲取一個許可
                    test(threadNum);
                    semaphore.release(); // 釋放一個許可
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        exec.shutdown();
    }

    private static void test(int threadNum) throws Exception {
        log.info("{}", threadNum);
        Thread.sleep(1000);
    }
}

我們在執(zhí)行 test(threadNum)方式前后包裹上acquire和release,這樣其實我們就相當(dāng)于一個單線程在執(zhí)行。當(dāng)執(zhí)行acquire后就只能等待執(zhí)行release后再執(zhí)行新的線程,然后我們在acquire()和release()都是沒有傳參也就是1,每次只允許一個線程執(zhí)行,如果我們改成

semaphore.acquire(3); // 獲取多個許可
test(threadNum);
semaphore.release(3); // 釋放多個許可

那么我們就是每3個3個執(zhí)行直到把線程池中的線程執(zhí)行完。在打印的日志中我們也可以看到是每三個每三個打印。

假設(shè)我們的數(shù)據(jù)庫允許獲取連接是3剩余的獲取線程我們不想要只想丟棄改如何實現(xiàn)?
Semaphore提供了一個嘗試獲取許可的方法,tryAcquire()嘗試獲取許可成功就執(zhí)行,嘗試獲取許可失敗就丟棄線程。下面看代碼
@Slf4j
public class SemaphoreExample3 {

    private final static int threadCount = 20;

    public static void main(String[] args) throws Exception {

        ExecutorService exec = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < threadCount; i++) {
            final int threadNum = i;
            exec.execute(() -> {
                try {
                    if (semaphore.tryAcquire()) { // 嘗試獲取一個許可
                        test(threadNum);
                        semaphore.release(); // 釋放一個許可
                    }
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        exec.shutdown();
    }

    private static void test(int threadNum) throws Exception {
        log.info("{}", threadNum);
        Thread.sleep(1000);
    }
}

這段代碼執(zhí)行結(jié)果就只打印了3行日志,其他的線程就被丟棄了。tryAcquire()共提供如下幾種方法。

我們用一個例子來演示一下參數(shù)的方法的使用。

@Slf4j
public class SemaphoreExample4 {

    private final static int threadCount = 20;

    public static void main(String[] args) throws Exception {

        ExecutorService exec = Executors.newCachedThreadPool();

        final Semaphore semaphore = new Semaphore(3);

        for (int i = 0; i < threadCount; i++) {
            final int threadNum = i;
            exec.execute(() -> {
                try {
                    if (semaphore.tryAcquire(5000, TimeUnit.MILLISECONDS)) { // 嘗試獲取一個許可
                        test(threadNum);
                        semaphore.release(); // 釋放一個許可
                    }
                } catch (Exception e) {
                    log.error("exception", e);
                }
            });
        }
        exec.shutdown();
    }

    private static void test(int threadNum) throws Exception {
        log.info("{}", threadNum);
        Thread.sleep(1000);
    }
}

這次我們使用的是一個tryAcquire(5000, TimeUnit.MILLISECONDS))方法,這個方法的第一個參數(shù)是表示等待5000毫秒,第二參數(shù)是表示多長時間嘗試一次,TimeUnit.MILLISECONDS表示1毫秒。這時候我們會發(fā)現(xiàn)20個線程都執(zhí)行了,為什么會這樣呢?因為我們在執(zhí)行時等待超時時間是5秒,每次執(zhí)行就是sleep 1秒,所以可以獲取成tryAcquire進(jìn)而執(zhí)行。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/77671.html

相關(guān)文章

  • AQS同步組件--ReentrantLock與鎖

    摘要:性能較好是因為避免了線程進(jìn)入內(nèi)核的阻塞狀態(tài)請求總數(shù)同時并發(fā)執(zhí)行的線程數(shù)我們首先使用聲明一個所得實例,然后使用進(jìn)行加鎖和解鎖操作。 ReentrantLock與鎖 Synchronized和ReentrantLock異同 可重入性:兩者都具有可重入性 鎖的實現(xiàn):Synchronized是依賴jvm實現(xiàn)的,ReentrantLock是jdk實現(xiàn)的。(我們可以理解為一個是操作系統(tǒng)層面的實現(xiàn)...

    dcr309duan 評論0 收藏0
  • Java多線程進(jìn)階(二十)—— J.U.C之synchronizer框架:Semaphore

    摘要:當(dāng)線程使用完共享資源后,可以歸還許可,以供其它需要的線程使用。所以,并不會阻塞調(diào)用線程。立即減少指定數(shù)目的可用許可數(shù)。方法用于將可用許可數(shù)清零,并返回清零前的許可數(shù)六的類接口聲明類聲明構(gòu)造器接口聲明 showImg(https://segmentfault.com/img/bVbfdnC?w=1920&h=1200); 本文首發(fā)于一世流云的專欄:https://segmentfault...

    boredream 評論0 收藏0
  • AbstractQueuedSynchronizer 原理分析 - 獨占/共享模式

    摘要:簡介抽象隊列同步器,以下簡稱出現(xiàn)在中,由大師所創(chuàng)作。獲取成功則返回,獲取失敗,線程進(jìn)入同步隊列等待。響應(yīng)中斷版的超時響應(yīng)中斷版的共享式獲取同步狀態(tài),同一時刻可能會有多個線程獲得同步狀態(tài)。 1.簡介 AbstractQueuedSynchronizer (抽象隊列同步器,以下簡稱 AQS)出現(xiàn)在 JDK 1.5 中,由大師 Doug Lea 所創(chuàng)作。AQS 是很多同步器的基礎(chǔ)框架,比如 ...

    pf_miles 評論0 收藏0
  • AbstractQueuedSynchronizer 原理分析 - 獨占/共享模式

    摘要:簡介抽象隊列同步器,以下簡稱出現(xiàn)在中,由大師所創(chuàng)作。獲取成功則返回,獲取失敗,線程進(jìn)入同步隊列等待。響應(yīng)中斷版的超時響應(yīng)中斷版的共享式獲取同步狀態(tài),同一時刻可能會有多個線程獲得同步狀態(tài)。 1.簡介 AbstractQueuedSynchronizer (抽象隊列同步器,以下簡稱 AQS)出現(xiàn)在 JDK 1.5 中,由大師 Doug Lea 所創(chuàng)作。AQS 是很多同步器的基礎(chǔ)框架,比如 ...

    gekylin 評論0 收藏0
  • 長文慎入-探索Java并發(fā)編程與高并發(fā)解決方案

    摘要:所有示例代碼請見下載于基本概念并發(fā)同時擁有兩個或者多個線程,如果程序在單核處理器上運行多個線程將交替地?fù)Q入或者換出內(nèi)存這些線程是同時存在的,每個線程都處于執(zhí)行過程中的某個狀態(tài),如果運行在多核處理器上此時,程序中的每個線程都 所有示例代碼,請見/下載于 https://github.com/Wasabi1234... showImg(https://upload-images.jians...

    SimpleTriangle 評論0 收藏0

發(fā)表評論

0條評論

DobbyKim

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<