关于多线程:CountDownLatch和Semaphore使用场景

CountDownLatch

CountDownLatch位于java.util.concurrent包下,利用它能够实现相似计数器的性能。比方有一个工作A,它要等到其它3工作实现能力执行,此时就能够用CountDownLatch来实现。

假如计数器的值为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));
    }
}

//能够炒菜了5082

Semaphore

Semaphore就是信号量,Semaphore能够阻塞线程并且能够管制同时拜访线程的个数,通过acquire()获取一个许可,如果没有获取到就持续期待,通过release()开释一个许可。Semaphore和锁有点相似,都能够管制对某个资源的拜访权限。

CountDownLatchSemaphore通常和线程池配合应用。Semaphore适宜管制并发数,CountDownLatch比拟适宜保障线程执行完后再执行其余解决,因而模仿并发时,应用两者联合起来是最好的。

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();

    }
}

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理