并发——并发模拟(三)

并发模拟工具

  1. Postman : Http 请求模拟工具

  2. Apache Bench(AB) : Apache 附带的工具,测试网站性能

  3. Jmeter : Apache 组织开发的压力测试工具

并发模拟代码

  1. CountDownLatch

CountDownLatch 能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为 0 时,表示所有的线程都已经完成了任务,然后在 CountDownLatch 上等待的线程就可以恢复执行任务。

  1. Semaphore

Semaphore 是一种基于计数的信号量。它可以设定一个阈值,也可称作并发数,基于此,多个线程竞争获取许可信号,做完自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。

Semaphore 可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为 1 的 Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。

并发代码

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
package modules;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class CountExample {

// 请求总数
public static int clientTotal = 5000;

// 同时并发执行的线程数
public static int threadTotal = 200;

public static int count = 0;

public static void main(String[] args) throws Exception {
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 {
//执行此方法用于获取执行许可,当总计未释放的许可数不超过200时,
//允许通行,否则线程阻塞等待,直到获取到许可。
semaphore.acquire();
add();
//释放许可
semaphore.release();
} catch (Exception e) {
//log.error("exception", e);
e.printStackTrace();
}
//闭锁减一
countDownLatch.countDown();
});
}
countDownLatch.await();//线程阻塞,直到闭锁值为0时,阻塞才释放,继续往下执行
executorService.shutdown();
log.info("count:{}", count);
}

private static void add() {
count++;
}
}

如果安装以上代码执行,并不一定是线程安全的,原因是 count++操作在并发环境下不能保证数据一致性问题,这就涉及到线程安全的问题,请看下一章

文章目录
  1. 1. 并发模拟工具
  2. 2. 并发模拟代码
    1. 2.1. 并发代码
|