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

4次阅读

共计 2097 个字符,预计需要花费 6 分钟才能阅读完成。

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

正文完
 0