多线程工具类,websocket
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
package com.ruoyi.common.utils.thread;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @date 2023/11/25 9:25
|
||||
**/
|
||||
@Data
|
||||
public class MultipleThreadListParam<T,R> {
|
||||
/**需要执行的方法*/
|
||||
private Function<List<T>,R> function;
|
||||
/**参数ID*/
|
||||
private List<T> list;
|
||||
public MultipleThreadListParam(Function<List<T>,R> function, List<T> list){
|
||||
this.function=function;
|
||||
this.list=list;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.ruoyi.common.utils.thread;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author wangqiong
|
||||
* @date 2023/11/25 9:25
|
||||
**/
|
||||
@Data
|
||||
public class MultipleThreadStringParam<T> {
|
||||
/**需要执行的方法*/
|
||||
private Function<String,T> function;
|
||||
/**参数ID*/
|
||||
private String ids;
|
||||
public MultipleThreadStringParam(Function<String,T> function, String ids){
|
||||
this.function=function;
|
||||
this.ids=ids;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,547 @@
|
||||
package com.ruoyi.common.utils.thread;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ruoyi.common.annotation.VoidFunction;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @description 多线程操作数据库,一个线程异常全部回滚
|
||||
* @Author wangqiong
|
||||
* @Date 2023/11/25 14:02
|
||||
* @Version V1.0
|
||||
**/
|
||||
@Slf4j
|
||||
public class MultipleThreadWorkUtil {
|
||||
private static int SIMPLE_TIME_COUNT=1000;
|
||||
|
||||
public static <R,A>List<R> exec(Function<List<A>,R> execFun, List<A> list){
|
||||
List<R> returnList=new ArrayList<>();
|
||||
if(CollectionUtil.isEmpty(list)){
|
||||
return returnList;
|
||||
}
|
||||
if(list.size()<SIMPLE_TIME_COUNT){
|
||||
return Arrays.asList(execFun.apply(list));
|
||||
}
|
||||
int times=list.size()/SIMPLE_TIME_COUNT;
|
||||
if(list.size()%SIMPLE_TIME_COUNT>0){
|
||||
times++;
|
||||
}
|
||||
CountDownLatch mainLatch=new CountDownLatch(1);
|
||||
//监控子线程
|
||||
CountDownLatch threadLatch=new CountDownLatch(times);
|
||||
//根据子线程执行结果判断是否需要回滚
|
||||
BlockingDeque<Boolean> resultList=new LinkedBlockingDeque<>();
|
||||
//必须使用对象,如果使用变量会造成线程之间不能共享变量值
|
||||
RollBack rollBack=new RollBack(false);
|
||||
ExecutorService executorService=Executors.newFixedThreadPool(times);
|
||||
List<Future<R>> futureList=new ArrayList<>();
|
||||
for (int i = 0; i <times ; i++) {
|
||||
if(i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT<list.size()){
|
||||
// 创建子线程
|
||||
Future<R> future=executorService.submit(new ExecThread(mainLatch,threadLatch,rollBack,resultList,list.subList(i*SIMPLE_TIME_COUNT,i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT),execFun));
|
||||
futureList.add(future);
|
||||
}else{
|
||||
Future<R> future=executorService.submit(new ExecThread(mainLatch,threadLatch,rollBack,resultList,list.subList(i*SIMPLE_TIME_COUNT,list.size()),execFun));
|
||||
futureList.add(future);
|
||||
}
|
||||
}
|
||||
setResult(executorService,returnList,futureList,resultList,
|
||||
mainLatch,threadLatch,rollBack,times);
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static <A>void exec(VoidFunction<Set<A>> execFun, Set<A> set){
|
||||
if(set.size()<SIMPLE_TIME_COUNT){
|
||||
execFun.apply(set);
|
||||
return;
|
||||
}
|
||||
int times=set.size()/SIMPLE_TIME_COUNT;
|
||||
if(set.size()%SIMPLE_TIME_COUNT>0){
|
||||
times++;
|
||||
}
|
||||
CountDownLatch mainLatch=new CountDownLatch(1);
|
||||
//监控子线程
|
||||
CountDownLatch threadLatch=new CountDownLatch(times);
|
||||
//根据子线程执行结果判断是否需要回滚
|
||||
BlockingDeque<Boolean> resultList=new LinkedBlockingDeque<>();
|
||||
//必须使用对象,如果使用变量会造成线程之间不能共享变量值
|
||||
RollBack rollBack=new RollBack(false);
|
||||
ExecutorService executorService=Executors.newFixedThreadPool(times);
|
||||
List<A> list=new ArrayList<>(set);
|
||||
List<Future> futureList=new ArrayList<>();
|
||||
for (int i = 0; i <times ; i++) {
|
||||
Future future;
|
||||
if(i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT<list.size()){
|
||||
future=executorService.submit(new VoidExecThread(mainLatch,threadLatch,rollBack,resultList,list.subList(i*SIMPLE_TIME_COUNT,i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT),execFun));
|
||||
}else{
|
||||
future=executorService.submit(new VoidExecThread(mainLatch,threadLatch,rollBack,resultList,list.subList(i*SIMPLE_TIME_COUNT,list.size()),execFun));
|
||||
}
|
||||
futureList.add(future);
|
||||
}
|
||||
/**存放子线程返回结果*/
|
||||
List<Boolean> backUpResult=new ArrayList<>();
|
||||
try{
|
||||
//
|
||||
boolean await=threadLatch.await(times*3,TimeUnit.SECONDS);
|
||||
if(!await){
|
||||
rollBack.setRollBack(true);
|
||||
}else{
|
||||
//查看执行情况,如果有存在需要回滚的线程,则全部回滚
|
||||
for (int i = 0; i <times ; i++) {
|
||||
Boolean result=resultList.take();
|
||||
backUpResult.add(result);
|
||||
if(result){
|
||||
/**有线程执行异常,需要回滚子线程*/
|
||||
rollBack.setRollBack(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
throw new ServiceException(e.getMessage());
|
||||
}finally {
|
||||
//子线程再次继续执行
|
||||
mainLatch.countDown();
|
||||
executorService.shutdown();
|
||||
}
|
||||
/**检查子线程是否有异常,有异常整体回滚*/
|
||||
for (int i = 0; i <times ; i++) {
|
||||
if(CollectionUtil.isNotEmpty(backUpResult)){
|
||||
Boolean result=backUpResult.get(i);
|
||||
if(result){
|
||||
/**有线程执行异常,需要回滚子线程*/
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}else{
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}
|
||||
for (Future future : futureList) {
|
||||
try {
|
||||
future.get();
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <R>List<R> execFun(MultipleThreadStringParam<R>...params){
|
||||
List<R> returnList=new ArrayList<>();
|
||||
if(ArrayUtil.isEmpty(params)){
|
||||
return returnList;
|
||||
}
|
||||
List<Integer> threadCountList=new ArrayList<>();
|
||||
for (MultipleThreadStringParam param : params) {
|
||||
List<String> idList= Arrays.asList(param.getIds().split(Constants.SPLIT_COMMA));
|
||||
if(idList.size()<SIMPLE_TIME_COUNT){
|
||||
threadCountList.add(1);
|
||||
}else{
|
||||
if(idList.size()%SIMPLE_TIME_COUNT>0){
|
||||
threadCountList.add(idList.size()/SIMPLE_TIME_COUNT+1);
|
||||
}else{
|
||||
threadCountList.add(idList.size()/SIMPLE_TIME_COUNT);
|
||||
}
|
||||
}
|
||||
}
|
||||
int times=0;
|
||||
for (Integer count : threadCountList) {
|
||||
times+=count;
|
||||
}
|
||||
CountDownLatch mainLatch=new CountDownLatch(1);
|
||||
//监控子线程
|
||||
CountDownLatch threadLatch=new CountDownLatch(times);
|
||||
//根据子线程执行结果判断是否需要回滚
|
||||
BlockingDeque<Boolean> resultList=new LinkedBlockingDeque<>();
|
||||
//必须使用对象,如果使用变量会造成线程之间不能共享变量值
|
||||
RollBack rollBack=new RollBack(false);
|
||||
ExecutorService executorService=Executors.newFixedThreadPool(times);
|
||||
List<Future<R>> futureList=new ArrayList<>();
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
MultipleThreadStringParam param=params[i];
|
||||
List<String> idList= Arrays.asList(param.getIds().split(Constants.SPLIT_COMMA));
|
||||
for (int j = 0; j <threadCountList.get(i) ; j++) {
|
||||
if(j*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT<idList.size()){
|
||||
Future<R> future=executorService.submit(new ExecByIdsStringThread<>(mainLatch,threadLatch,rollBack,resultList,StrUtil.join(Constants.SPLIT_COMMA,idList.subList(j*SIMPLE_TIME_COUNT,j*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT)),param.getFunction()));
|
||||
futureList.add(future);
|
||||
}else{
|
||||
Future<R> future=executorService.submit(new ExecByIdsStringThread(mainLatch,threadLatch,rollBack,resultList,StrUtil.join(Constants.SPLIT_COMMA,idList.subList(j*SIMPLE_TIME_COUNT,idList.size())),param.getFunction()));
|
||||
futureList.add(future);
|
||||
}
|
||||
}
|
||||
}
|
||||
setResult(executorService,returnList,futureList,resultList,
|
||||
mainLatch,threadLatch,rollBack,times);
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static <R>List<R> execByIds(Function<String,R> execFun,String ids){
|
||||
List<R> returnList=new ArrayList<>();
|
||||
if(StrUtil.isEmpty(ids)){
|
||||
return returnList;
|
||||
}
|
||||
List<String> idList= Arrays.asList(ids.split(Constants.SPLIT_COMMA));
|
||||
if(idList.size()<SIMPLE_TIME_COUNT){
|
||||
return Arrays.asList(execFun.apply(ids));
|
||||
}
|
||||
int times=idList.size()/SIMPLE_TIME_COUNT;
|
||||
if(idList.size()%SIMPLE_TIME_COUNT>0){
|
||||
times++;
|
||||
}
|
||||
CountDownLatch mainLatch=new CountDownLatch(1);
|
||||
//监控子线程
|
||||
CountDownLatch threadLatch=new CountDownLatch(times);
|
||||
//根据子线程执行结果判断是否需要回滚
|
||||
BlockingDeque<Boolean> resultList=new LinkedBlockingDeque<>();
|
||||
//必须使用对象,如果使用变量会造成线程之间不能共享变量值
|
||||
RollBack rollBack=new RollBack(false);
|
||||
ExecutorService executorService=Executors.newFixedThreadPool(times);
|
||||
List<Future<R>> futureList=new ArrayList<>();
|
||||
for (int i = 0; i <times ; i++) {
|
||||
if(i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT<idList.size()){
|
||||
Future<R> future=executorService.submit(new ExecByIdsStringThread<>(mainLatch,threadLatch,rollBack,resultList,StrUtil.join(Constants.SPLIT_COMMA,idList.subList(i*SIMPLE_TIME_COUNT,i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT)),execFun));
|
||||
futureList.add(future);
|
||||
}else{
|
||||
Future<R> future=executorService.submit(new ExecByIdsStringThread(mainLatch,threadLatch,rollBack,resultList,StrUtil.join(Constants.SPLIT_COMMA,idList.subList(i*SIMPLE_TIME_COUNT,idList.size())),execFun));
|
||||
futureList.add(future);
|
||||
}
|
||||
}
|
||||
setResult(executorService,returnList,futureList,resultList,
|
||||
mainLatch,threadLatch,rollBack,times);
|
||||
return returnList;
|
||||
}
|
||||
|
||||
public static <R>List<R> execByIds(Function<List<String>,List<R>> execFun,List<String> idList){
|
||||
List<R> returnList=new ArrayList<>();
|
||||
if(CollectionUtil.isEmpty(idList)){
|
||||
return returnList;
|
||||
}
|
||||
if(idList.size()<SIMPLE_TIME_COUNT){
|
||||
return execFun.apply(idList);
|
||||
}
|
||||
int times=idList.size()/SIMPLE_TIME_COUNT;
|
||||
if(idList.size()%SIMPLE_TIME_COUNT>0){
|
||||
times++;
|
||||
}
|
||||
CountDownLatch mainLatch=new CountDownLatch(1);
|
||||
//监控子线程
|
||||
CountDownLatch threadLatch=new CountDownLatch(times);
|
||||
//根据子线程执行结果判断是否需要回滚
|
||||
BlockingDeque<Boolean> resultList=new LinkedBlockingDeque<>();
|
||||
//必须使用对象,如果使用变量会造成线程之间不能共享变量值
|
||||
RollBack rollBack=new RollBack(false);
|
||||
ExecutorService executorService=Executors.newFixedThreadPool(times);
|
||||
List<Future<List<R>>> futureList=new ArrayList<>();
|
||||
for (int i = 0; i <times ; i++) {
|
||||
if(i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT<idList.size()){
|
||||
Future<List<R>> future=executorService.submit(new ExecByIdsStringListThread<>(mainLatch,threadLatch,rollBack,resultList,idList.subList(i*SIMPLE_TIME_COUNT,i*SIMPLE_TIME_COUNT+SIMPLE_TIME_COUNT),execFun));
|
||||
futureList.add(future);
|
||||
}else{
|
||||
Future<List<R>> future=executorService.submit(new ExecByIdsStringListThread(mainLatch,threadLatch,rollBack,resultList,idList.subList(i*SIMPLE_TIME_COUNT,idList.size()),execFun));
|
||||
futureList.add(future);
|
||||
}
|
||||
}
|
||||
/**存放子线程返回结果*/
|
||||
List<Boolean> backUpResult=new ArrayList<>();
|
||||
try{
|
||||
//
|
||||
boolean await=threadLatch.await(times*3,TimeUnit.SECONDS);
|
||||
if(!await){
|
||||
rollBack.setRollBack(true);
|
||||
}else{
|
||||
//查看执行情况,如果有存在需要回滚的线程,则全部回滚
|
||||
for (int i = 0; i <times ; i++) {
|
||||
Boolean result=resultList.take();
|
||||
backUpResult.add(result);
|
||||
if(result){
|
||||
/**有线程执行异常,需要回滚子线程*/
|
||||
rollBack.setRollBack(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}finally {
|
||||
//子线程再次继续执行
|
||||
mainLatch.countDown();
|
||||
executorService.shutdown();
|
||||
}
|
||||
/**检查子线程是否有异常,有异常整体回滚*/
|
||||
for (int i = 0; i <times ; i++) {
|
||||
if(CollectionUtil.isNotEmpty(backUpResult)){
|
||||
Boolean result=backUpResult.get(i);
|
||||
if(result){
|
||||
/**有线程执行异常,需要回滚子线程*/
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}else{
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}
|
||||
for (Future<List<R>> future : futureList) {
|
||||
try {
|
||||
returnList.addAll(future.get());
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}
|
||||
return returnList;
|
||||
}
|
||||
|
||||
private static <R>void setResult(ExecutorService executorService,List<R> returnList,List<Future<R>> futureList,BlockingDeque<Boolean> resultList
|
||||
,CountDownLatch mainLatch,CountDownLatch threadLatch,RollBack rollBack,int times){
|
||||
/**存放子线程返回结果*/
|
||||
List<Boolean> backUpResult=new ArrayList<>();
|
||||
try{
|
||||
//
|
||||
boolean await=threadLatch.await(times*3,TimeUnit.SECONDS);
|
||||
if(!await){
|
||||
rollBack.setRollBack(true);
|
||||
}else{
|
||||
//查看执行情况,如果有存在需要回滚的线程,则全部回滚
|
||||
for (int i = 0; i <times ; i++) {
|
||||
Boolean result=resultList.take();
|
||||
backUpResult.add(result);
|
||||
if(result){
|
||||
/**有线程执行异常,需要回滚子线程*/
|
||||
rollBack.setRollBack(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}catch (InterruptedException e){
|
||||
e.printStackTrace();
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}finally {
|
||||
//子线程再次继续执行
|
||||
mainLatch.countDown();
|
||||
executorService.shutdown();
|
||||
}
|
||||
/**检查子线程是否有异常,有异常整体回滚*/
|
||||
for (int i = 0; i <times ; i++) {
|
||||
if(CollectionUtil.isNotEmpty(backUpResult)){
|
||||
Boolean result=backUpResult.get(i);
|
||||
if(result){
|
||||
/**有线程执行异常,需要回滚子线程*/
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}else{
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}
|
||||
for (Future<R> future : futureList) {
|
||||
try {
|
||||
returnList.add(future.get());
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class QueryThread<R> implements Callable<List<R>>{
|
||||
private String ids;
|
||||
private Function<String,List<R>> execFun;
|
||||
public QueryThread(String ids,Function<String,List<R>> execFun){
|
||||
this.ids=ids;
|
||||
this.execFun=execFun;
|
||||
}
|
||||
@Override
|
||||
public List<R> call(){
|
||||
return execFun.apply(ids);
|
||||
}
|
||||
}
|
||||
|
||||
static class ExecThread<T,R> implements Callable<R>{
|
||||
/**主线程监控*/
|
||||
private CountDownLatch mainLatch;
|
||||
/**子线程监控*/
|
||||
private CountDownLatch threadLatch;
|
||||
/**是否回滚*/
|
||||
private RollBack rollBack;
|
||||
private BlockingDeque<Boolean> resultList;
|
||||
private List<T> list;
|
||||
private Function<List<T>,R> execFun;
|
||||
public ExecThread(CountDownLatch mainLatch,CountDownLatch threadLatch,RollBack rollBack,BlockingDeque<Boolean> resultList,List<T> list,Function<List<T>,R> execFun){
|
||||
this.mainLatch=mainLatch;
|
||||
this.threadLatch=threadLatch;
|
||||
this.rollBack=rollBack;
|
||||
this.resultList=resultList;
|
||||
this.list=list;
|
||||
this.execFun=execFun;
|
||||
}
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R call(){
|
||||
// 是否回滚
|
||||
Boolean result=false;
|
||||
R r=null;
|
||||
try{
|
||||
// 对数据库进行操作
|
||||
r=execFun.apply(list);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
result=true;
|
||||
}
|
||||
resultList.add(result);
|
||||
// 子线程-1,切换到主线程执行
|
||||
threadLatch.countDown();
|
||||
try{
|
||||
// 等待主线程执行
|
||||
mainLatch.await();
|
||||
}catch (InterruptedException e){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
if(rollBack.getRollBack()){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
static class VoidExecThread<T> implements Runnable{
|
||||
/**主线程监控*/
|
||||
private CountDownLatch mainLatch;
|
||||
/**子线程监控*/
|
||||
private CountDownLatch threadLatch;
|
||||
/**是否回滚*/
|
||||
private RollBack rollBack;
|
||||
private BlockingDeque<Boolean> resultList;
|
||||
private List<T> list;
|
||||
private VoidFunction<Set<T>> execFun;
|
||||
public VoidExecThread(CountDownLatch mainLatch,CountDownLatch threadLatch,RollBack rollBack,BlockingDeque<Boolean> resultList,List<T> list,VoidFunction<Set<T>> execFun){
|
||||
this.mainLatch=mainLatch;
|
||||
this.threadLatch=threadLatch;
|
||||
this.rollBack=rollBack;
|
||||
this.resultList=resultList;
|
||||
this.list=list;
|
||||
this.execFun=execFun;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
Boolean result=false;
|
||||
try{
|
||||
execFun.apply(new HashSet<>(list));
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
result=true;
|
||||
}
|
||||
resultList.add(result);
|
||||
threadLatch.countDown();
|
||||
try{
|
||||
mainLatch.await();
|
||||
}catch (InterruptedException e){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
if(rollBack.getRollBack()){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class ExecByIdsStringThread<R> implements Callable<R>{
|
||||
/**主线程监控*/
|
||||
private CountDownLatch mainLatch;
|
||||
/**子线程监控*/
|
||||
private CountDownLatch threadLatch;
|
||||
/**是否回滚*/
|
||||
private RollBack rollBack;
|
||||
private BlockingDeque<Boolean> resultList;
|
||||
private String ids;
|
||||
private Function<String,R> execFun;
|
||||
public ExecByIdsStringThread(CountDownLatch mainLatch,CountDownLatch threadLatch,RollBack rollBack,BlockingDeque<Boolean> resultList,String ids,Function<String,R> execFun){
|
||||
this.mainLatch=mainLatch;
|
||||
this.threadLatch=threadLatch;
|
||||
this.rollBack=rollBack;
|
||||
this.resultList=resultList;
|
||||
this.ids=ids;
|
||||
this.execFun=execFun;
|
||||
}
|
||||
@Override
|
||||
public R call(){
|
||||
Boolean result=false;
|
||||
R r=null;
|
||||
try{
|
||||
r=execFun.apply(ids);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
result=true;
|
||||
}
|
||||
resultList.add(result);
|
||||
threadLatch.countDown();
|
||||
try{
|
||||
mainLatch.await();
|
||||
}catch (InterruptedException e){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
if(rollBack.getRollBack()){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static class ExecByIdsStringListThread<R> implements Callable<R>{
|
||||
/**主线程监控*/
|
||||
private CountDownLatch mainLatch;
|
||||
/**子线程监控*/
|
||||
private CountDownLatch threadLatch;
|
||||
/**是否回滚*/
|
||||
private RollBack rollBack;
|
||||
private BlockingDeque<Boolean> resultList;
|
||||
private List<String> ids;
|
||||
private Function<List<String>,R> execFun;
|
||||
public ExecByIdsStringListThread(CountDownLatch mainLatch,CountDownLatch threadLatch,RollBack rollBack,BlockingDeque<Boolean> resultList,List<String> ids,Function<List<String>,R> execFun){
|
||||
this.mainLatch=mainLatch;
|
||||
this.threadLatch=threadLatch;
|
||||
this.rollBack=rollBack;
|
||||
this.resultList=resultList;
|
||||
this.ids=ids;
|
||||
this.execFun=execFun;
|
||||
}
|
||||
@Override
|
||||
public R call(){
|
||||
Boolean result=false;
|
||||
R r=null;
|
||||
try{
|
||||
r=execFun.apply(ids);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
result=true;
|
||||
}
|
||||
resultList.add(result);
|
||||
threadLatch.countDown();
|
||||
try{
|
||||
mainLatch.await();
|
||||
}catch (InterruptedException e){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
if(rollBack.getRollBack()){
|
||||
throw new ServiceException("多线程执行异常");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
static class RollBack{
|
||||
private Boolean rollBack;
|
||||
public RollBack(Boolean rollBack){
|
||||
this.rollBack=rollBack;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user