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
可以阻塞线程并且可以控制同时访问线程的个数,通过acquire()
获取一个许可,如果没有获取到就继续等待,通过release()
释放一个许可。Semaphore
和锁有点类似,都可以控制对某个资源的访问权限。
CountDownLatch
和Semaphore
通常和线程池配合使用。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();
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。