【java】【多线程】等待开启的多个线程都执⾏完成,再做事情,怎么实现今天在controller中写⼀个接⼝⽤来测试模拟多个请求同时到达下订单的情况,
怎么能有效保证⾼并发下的库存和销量的⼀致性呢?【具体实现⽅法:】
====
那么好,在这个接⼝中,开启多线程模拟了多个⽤户请求同时到达的状况,现在想在多个线程都执⾏完了以后再统⼀返回结果给前台,哪些请求成功了,哪些请求失败了。
====
所以现在的需求是怎么能实现等待多个线程都执⾏完了以后再做事情~~~
===================================================================================================================================其实想要实现这个需求:等待多个线程执⾏完了,再做事情。
有两种⽅法,可以应对不同的情况:
分别是CountDownLatch和CyclicBarrier
=================================================================================================================================== CountDownLatch和CyclicBarrier简单⽐较:
CountDownLatch CyclicBarrier
软件包urrent urrent
适⽤情
主线程等待多个⼯作线程结束多个线程之间互相等待,直到所有线程达到⼀个障碍点(Barrier point)
主要⽅法CountDownLatch(int count) (主线程调⽤)
初始化计数
CountDownLatch.await (主线程调⽤)
阻塞,直到等待计数为0解除阻塞
计数减⼀(⼯作线程调⽤)
CyclicBarrier(int parties,  barrierAction) //初始化参与者数量和障碍点执⾏Action,Action可选。
由主线程初始化
CyclicBarrier.await() //由参与者调⽤
阻塞,直到所有线程达到屏障点
等待结束各线程之间不再互相影响,可以继续做⾃⼰的事情。不再执
⾏下⼀个⽬标⼯作。
在屏障点达到后,允许所有线程继续执⾏,达到下⼀个⽬标。可以重复使⽤CyclicBarrier
异常如果其中⼀个线程由于中断,错误,或超时导致永久离开屏障点,其他线程也将抛出异常。
其他如果BarrierAction不依赖于任何Party中的所有线程,那么在任何party中的⼀个线程被释放的时候,可以直接运⾏这个Action。
If(barrier.await()==2)
{
//do action
}
CountDownLatch 使⽤⽰例代码:
主线程调⽤
⼯作线程调⽤
package com.sxd.swapping.utils;
import org.junit.Test;
import urrent.CountDownLatch;
public class ThreadTest {
/**
* 主线程
*/
@Test
public void  test(){
//开启10个多线程
int threadCount = 10;
//所有线程阻塞,然后统⼀开始
CountDownLatch begin = new CountDownLatch(1);
//主线程阻塞,直到所有分线程执⾏完毕
CountDownLatch end = new CountDownLatch(threadCount);
//开始多线程
for (Integer i = 0; i < threadCount; i++) {
Runnable runnable = dealSomeThing(i,begin,end);
new Thread(runnable).start();
}
//多个线程都执⾏结束
try {
end.await();
System.out.println("多个线程都执⾏结束,可以做⾃⼰的事情了");
java做什么的} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("多线程执⾏中出错了,凉凉了");
}
}
/**
* ⼯作线程
* 本⽅法是在构造多线程要做的事情
*
* =====================可以做的事===================
* 当然可以传⼊ConcurrentHashMap之类的线程安全的类
* 来记录线程中的处理结果之类的
* 最后在多线程都执⾏完了以后就可以对处理结果进⾏操作了
* ==================================================
*
* @param threadNum 当前线程编号
* @param begin
* @param end
* @return
*/
private Runnable dealSomeThing(int threadNum, CountDownLatch begin, CountDownLatch end){
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println("线程"+threadNum+":--------------------->开始⼯作");
begin.await();
System.out.println("线程"+threadNum+"做具体的事情,⽐如去service调⽤具体的⽅法做什么操作之类的");
System.out.println("线程"+threadNum+":--------------------->结束⼯作");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
return runnable;
}
}
最后实现的结果:
========================================================================================= CyclicBarrier使⽤⽰例代码:
现在还没⽤到,空闲了再补充