Java JUI
之并发编程,CountDownLatch
和 Semaphone
的应用
CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复执行任务。
CountDownLatch(int count):count为计数器的初始值(一般需要多少个线程执行,count就设为几)。
列子:
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
public class ThreadTest extends Thread{
public static void main(String[] args) throws InterruptedException, ExecutionException {
/*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.AbortPolicy());*/
ExecutorService executorService = Executors.newWorkStealingPool();
//定义一个计数器
CountDownLatch countDownLatch = new CountDownLatch(20);
//把各个地区统计数据放到一个map里面,key:区域 value:销量 、 统计用的时间
for (int i = 0; i < 20; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
//销量统计的方法
countDownLatch.countDown();
}
};
executorService.execute(runnable);
}
//等待形成全部执行完成
countDownLatch.await();
//把map打印出来
log.info("end ----");
}
}
一个计数信号量,从概念上将,信号量维护了一个许可集,如有必要,在许可可用前会阻塞每一个acquire(),然后在获取该许可。每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对可用许可的号码进行计数,并采取相应的行动
具体常用的方法有:
方法 | 说明 |
---|---|
acquire() | 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断 |
release() | 释放一个许可,将其返回给信号量 |
设置许可数量,Semaphore semaphore = new Semaphore(3);
一般acquire()都会抛出异常,release在finally中执行
例子:
汽车抢位
public static void main(String[] args) {
/**
* 10辆车 4个停车位的问题
*/
//初始化信号量
Semaphore semaphore = new Semaphore(4);
ExecutorService executorService = Executors.newFixedThreadPool(100);
for (int i = 0; i < 10; i++) {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
//获取许可
semaphore.acquire();
System.out.println("进入车位.....");
TimeUnit.SECONDS.sleep((int) (Math.random() * 10));
System.out.println("离开车位.....");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放许可
semaphore.release();
}
}
};
executorService.execute(runnable);
}
}
CountDownLatch 是一个同步辅助类,它可以让一个或多个线程等待其他线程完成操作之后再继续执行。它通过一个计数器来实现,初始化时指定一个计数值,当某些操作完成时可以调用 countDown() 方法来减小计数值,而等待的线程可以调用 await() 方法来阻塞直到计数值为0。
Semaphore 是一个计数信号量,用来控制同时访问特定资源的线程数量。它通过指定许可数来初始化,线程可以通过 acquire() 方法获取许可,执行相应的操作,然后通过 release() 方法释放许可。
CountDownLatch 主要用于一个或多个线程等待其他线程的完成,而 Semaphore 主要用于控制同时访问特定资源的线程数量。它们都是多线程编程中常用的同步工具,可以帮助我们有效地管理线程之间的协调和资源访问。