基础框架搭建和并发模拟工具,代码
(1)基础框架搭建
码云项目 :https://gitee.com/dzxmy/concurrency
(2)并发模拟
(3)CountDownLatch
通常用来 保证 几个线程执行完成之后,再执行其他的代码
(4)Semaphore
控制同一时刻的并发量
@Slf4j
@NotThreadSafe
public class ConcurrencyTest {
//请求次数
private static int clientTotal = 5000;
//允许同时运行的线程数
private static int threadTotal = 200;
//计数
public static int count = 0;
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
for (int i = 0; i < clientTotal; i++) {
executorService.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (InterruptedException e) {
log.error("exception", e);
}
countDownLatch.countDown();
});
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.shutdown();
log.info("count:{}", count);
}
private static void add() {
count++;
}
}
运行代码可以看到每次计数的结果都不一样,并且可能不是5000,因为同一时刻200个线程同时运行将count加1,而count并不是对于线程之间可见,可能两个线程在读取count的时候结果是一样的,同时对值加+1,因此就会造成最后的结果可能不是5000,这种方式是线程不安全的。