Semaphore信号量 协调多线程合理使用公共资源
GitHub: link. 欢迎star
注意:本篇博客风格(不多比比就是撸代码!!!)
一、使用场景
- 多线程环境下,借助Semaphore信号量协调各个线程, 以保证它们能够正确、合理的使用公共资源。
- 初始化,许可数量:new Semaphore(permits);
- 获取许可证:semaphore.acquire();
- 释放许可,增加许可数量:semaphore.release();
二、SemaphoreTest.java
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore;
/**
* @author Andon
* 2022/5/20
*/
@Slf4j
public class SemaphoreTest {
private static int permits = 3;
private static Semaphore semaphore = new Semaphore(permits);
@Test
public void semaphore() throws Exception {
int num = 5;
log.info("有{}个位置可以做核酸", permits);
log.info("来了{}个人做核酸", num);
List<CompletableFuture<Void>> completableFutures = new ArrayList<>();
for (int i = 0; i < num; i++) {
semaphore.acquire();
CompletableFuture<Void> completableFuture = CompletableFuture.runAsync(() -> {
try {
long stop = (long) (Math.random() * 10 + 1);
log.info("{}开始做核酸,耗时{}秒", Thread.currentThread().getName(), stop);
Thread.sleep(stop * 1000);
} catch (Exception ignored) {
} finally {
log.info("{}做完核酸准备离开", Thread.currentThread().getName());
semaphore.release();
log.info("{}已经离开了!!", Thread.currentThread().getName());
}
});
completableFutures.add(completableFuture);
}
CompletableFuture<Void> completableFuture = CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0]));
completableFuture.join();
}
}
三、测试
附加:中断分片线程
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* @author Andon
* 2022/5/20
*/
@Slf4j
public class ThreadTnterruptTest {
/**
* 中断分片线程 测试
*/
@Test
public void interruptTest() throws ExecutionException, InterruptedException {
List<Thread> threads = new ArrayList<>();
ExecutorService executorService = Executors.newFixedThreadPool(8);
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < 5; i++) {
int finalI = i + 1;
Future<?> future = executorService.submit(() -> {
Thread thread = Thread.currentThread();
threads.add(thread);
try {
log.info("[{}] - thread start!! finalI={}", thread.getId(), finalI);
Thread.sleep(finalI * 1000);
threadCheck();
if (finalI == 3) {
throw new Exception("Exception");
}
log.info("[{}] - thread end!! finalI={}", thread.getId(), finalI);
} catch (Exception e) {
log.info("[{}] - thread interrupt!!", thread.getId());
interrupt(threads);
}
});
futures.add(future);
}
for (Future<?> future : futures) {
future.get();
}
log.info("end!!");
}
/**
* 线程检查
* <p>
* 在线程中计划中断的地方执行
*/
public void threadCheck() throws InterruptedException {
Thread.sleep(10);
}
/**
* 中断线程
* <p>
* 会在线程检查代码执行时,抛出异常来中断线程
*/
public void interrupt(List<Thread> threads) {
for (Thread thread : threads) {
thread.interrupt();
}
}
}
GitHub: link. 欢迎star