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)); } }
//能够炒菜了5082java
Semaphore
就是信号量,Semaphore
能够阻塞线程而且能够控制同时访问线程的个数,经过acquire()
获取一个许可,若是没有获取到就继续等待,经过release()
释放一个许可。Semaphore
和锁有点相似,均可以控制对某个资源的访问权限。
CountDownLatch
和Semaphore
一般和线程池配合使用。Semaphore适合控制并发数,CountDownLatch比较适合保证线程执行完后再执行其余处理,所以模拟并发时,使用二者结合起来是最好的。springSemaphore能够用来作流量分流,特别是对公共资源有限的场景,好比数据库链接。
假设有这个的需求,读取几万个文件的数据到数据库中,因为文件读取是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(); } }