高并发模拟,多个线程同时发起请求
两种方案:
- CyclicBarrier:栅栏,所有的线程必须同时到达栅栏位置,才能继续执行。
- CountDownLatch:计数器,一个线程或多个线程一直等待,直到其他线程执行的操作完成。
1、CyclicBarrier
- 适用在多线程相互等待,直到到达一个屏障点。并且CyclicBarrier是可重用的。
- 下面的列子,设置线程阻塞200个,但发起线程400个,这样会被分为两批,前200个线程相互等待,一起请求,后200个线程相互等待,一起请求。
public class CurrentChatTest {
//定义CyclicBarrier 的屏障,需要等多少个线程到了才发起请求
CyclicBarrier cyclicBarrier = new CyclicBarrier(200);
private void runThread() {
//定义线程池
ExecutorService executorService = Executors.newFixedThreadPool(400);
//执行线程
for (int i = 0; i < 400; i++) {
executorService.submit(buildThread(i));
}
}
private Thread buildThread(int i) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("Thread:" + Thread.currentThread().getName() + "准备...");
//cyclicBarrier一定要等到满200个线程到了才往后执行
cyclicBarrier.await();
System.out.println("Thread:" + Thread.currentThread().getName() + "开始执行");
//do something
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.setName("name:" + i);
return thread;
}
public static void main(String[] args) {
CurrentChatTest currentChatTest = new CurrentChatTest();
currentChatTest.runThread();
}
}
2、CountDownLatch
CountDownLatch 就是一个计数器,让所有的线程等待,直到计数器的值为0时才让线程执行。
public class CurrentChatTest {
//定义一个CountDownLatch
CountDownLatch countDownLatch = new CountDownLatch(1);
public void countDownLatch() {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executorService.submit(createThread());
}
//计数器减一
countDownLatch.countDown();
}
//创建线程
private Thread createThread() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("Thread: "+Thread.currentThread().getName()+", 准备...");
countDownLatch.await();
//do something
System.out.println("Thread: "+Thread.currentThread().getName()+", 开始...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
return thread;
}
public static void main(String[] args) {
CurrentChatTest currentChatTest = new CurrentChatTest();
currentChatTest.countDownLatch();
}
}