CountDownLatch和Semaphore使用場景

CountDownLatch

CountDownLatch位於 java.util.concurrent包下,利用它能夠實現相似計數器的功能。好比有一個任務A,它要等到其它3任務完成才能執行,此時就能夠用 CountDownLatch來實現。

img

假設計數器的值爲2,線程A調用 await()方法以後,A線程就進入了等待狀態,以後其它線程中執行 countDown(),計數器就會-1,該操做線程繼續執行,當計數器從2編程0,線程A繼續執行。
package com.keytech.task;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


class TaskApplicationTests {
    //目標:炒菜
    //1.洗菜 5秒
    //2.買鹽 3秒
    public static void main(String[] args) throws InterruptedException {
        Executor executor=Executors.newFixedThreadPool(2);
        CountDownLatch countDownLatch=new CountDownLatch(2);
        long now = System.currentTimeMillis();
        //洗菜5秒
        executor.execute(()->{
             try{
                 Thread.sleep(5000);

             }catch (Exception e){
                 e.printStackTrace();
             }finally {
                 if(countDownLatch!=null){
                     countDownLatch.countDown();
                 }
             }
        });
        //買鹽3秒
        executor.execute(()->{
             try{
                 Thread.sleep(3000);
             }catch (Exception e){
                e.printStackTrace();
             }finally {
                 if(countDownLatch!=null){
                     countDownLatch.countDown();
                 }
             }
        });
        countDownLatch.await();
        System.out.println("能夠炒菜了"+(System.currentTimeMillis()-now));
    }
}

//能夠炒菜了5082java

Semaphore

image-20201226194300986

Semaphore就是信號量, Semaphore能夠阻塞線程而且能夠控制同時訪問線程的個數,經過 acquire()獲取一個許可,若是沒有獲取到就繼續等待,經過 release()釋放一個許可。 Semaphore和鎖有點相似,均可以控制對某個資源的訪問權限。

CountDownLatchSemaphore一般和線程池配合使用。Semaphore適合控制併發數,CountDownLatch比較適合保證線程執行完後再執行其餘處理,所以模擬併發時,使用二者結合起來是最好的。spring

Semaphore能夠用來作流量分流,特別是對公共資源有限的場景,好比數據庫鏈接。
假設有這個的需求,讀取幾萬個文件的數據到數據庫中,因爲文件讀取是IO密集型任務,能夠啓動幾十個線程併發讀取,可是數據庫鏈接數只有10個,這時就必須控制最多隻有10個線程可以拿到數據庫鏈接進行操做。這個時候,就可使用Semaphore作流量控制。數據庫

package com.keytech.task;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

/**
 * @className: SemaphoreTest
 * @description: TODO 類描述
 * @author: mac
 * @date: 2020/12/26
 **/
public class SemaphoreTest {
    public static void main(String[] args) {
        ExecutorService  executor=Executors.newFixedThreadPool(40);

        Semaphore  semaphore=new Semaphore(10);
        for (int i = 0; i < 40; i++) {
            executor.execute(()->{
                try {
                    semaphore.acquire();
                    System.out.println("處理數據中......");
                    Thread.sleep(3000);
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            });
        }
        executor.shutdown();

    }
}

相關文章
相關標籤/搜索