第一次并发模拟

关键源码

这是我的第一次并发模拟的演示例子,是使用SpringBoot搭建演示环境。虽然很简单,但是万丈高楼平地起,基础得打好~之后我会更加详实地补充高级内容!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//为输出方便,加log注解
@Slf4j
@NotThreadSafe //该自定义注解只是标示其为非线程安全类
public class ConcurrencyTest {

//请求总数量
public static int clientTotal = 5000;
//并发数量
public 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(() -> {
//核心方法执行前后需获取/释放信号量
//由于使用信号量可能会因执行中断而产生异常
//只有当semaphore.acquire()执行完(根据目前的并发数判断该线程是否允许被执行,否则会被阻塞)有返回效果,线程才会执行其核心方法
try {
semaphore.acquire();
add();
semaphore.release();
} catch (InterruptedException e) {
// e.printStackTrace();
log.error("中断异常InterruptedException:", e);
}
//执行闭锁,进行请求总数减一
countDownLatch.countDown();
});
}
//调用countDownLatch.await()方法保证目前已经**减为零**。
try {
countDownLatch.await();
//闭锁执行完毕,关闭线程池
executorService.shutdown();
log.info("计数count:{}",count);
} catch (InterruptedException e) {
// e.printStackTrace();
log.error("计数产生中断异常InterruptedException:", e);
}
}

//计数方法
private static void add() {
count++;
}
}
第一次运行结果

图

第二次运行结果

图

第三次运行结果

图

根据三次结果,显然该类是非线程安全的类。所以其前面标注上之前定义的注解。
SupriseMF wechat
欢迎关注微信订阅号【星球码】,分享学习编程奇淫巧技~
喜欢就支持我呀(*^∇^*)~

热评文章