多线程使用解决并带主动超时的问题
程序员文章站
2024-01-13 19:39:46
...
项目中有时我们需要更新很多记录的不同信息,因为数量多,操作耗时不确定,时长时短,还有可能操作到半卡住,既不断开也没返回结果,有可能等待数天的情况,这肯定不是我们希望的,所以在设计时我们希望,任务列表执行时,能主动控制方法执行的超时时间,如果超时了或有异常就抛出异常,同时每次触发进行具体的业务操作又是一连串完整的业务流程操作;串行处理是可以完成,但可能等待的时间比较长,所以设法有多路并行触发业务方法,同时又能控制主动超时,这样是最快的;于是设计思路如下:
1,业务执行方法,一个真正执行一连串完整的业务流程操作,无返回或返回的结果可以不理,执行业务方法的时间不确定,有长有短或一直连着;如:realUpdateInfo();
2,一个能主动控制超时的方法,其设计目的就是要求在规定时间内执行真正业务方法,如果执行不完就触发超时,业务方法出现异常也抛出异常,主要是只管触发执行和控制超时;如:updateInfoWithTimeout();
3,业务任务方法,使用线程池中多个线程同时并行触发任务;如:updateAllProductInfo();
参考例子如下:
package com.qyh.pro01.service.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.springframework.transaction.annotation.Transactional;
import com.qyh.pro01.model.Product;
/**
* @author shenzhenNBA
*
*/
public class InfoUpdateServiceImpl {
//单个线程池
//private static ExecutorService executorService2 = Executors.newSingleThreadExecutor();
//定义有100个线程的线程池
private static ExecutorService executorService = Executors.newFixedThreadPool(100);
/**
* 任务方法,使用线程池中100个线程同时并行触发任务
*/
public void updateAllProductInfo() {
List<Product> allProduct = new ArrayList<Product>();
//allProduct = prodcutDao.queryAll(); //假如数量巨大或更新比较费时
long timeoutNumber = 30*1000; //30秒
for (Product product : allProduct) {
this.updateInfoWithTimeout(timeoutNumber,product);
}
}
/**
* 带有主动超时的方法,如果是没必要等返回值的情况就不需要等待结果,只管触发执行,
* 其设计目的就是要求在规定时间内执行真正业务方法,如果执行不完就触发超时,业务方法出现异常也抛出异常
* @param timeoutNumber 仅对等待返回结果的有效
* @param productParam
* @return
*/
public String updateInfoWithTimeout(long timeoutNumber, Product productParam) {
String result = "no";
FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
return realUpdateInfo(productParam);
}
});
try {
//只管使用线程池里不同的线程触发真正的业务执行,使用线程池默认的超时时间处理超时
//业务不需要等待结果,无返回或返回的结果可以不理的情况,
executorService.execute(futureTask);
result = "ok";
//此处代码会等待返回结果,但如果超时还是触发超时,仅对必须等待返回结果才能进行后续操作
//result = futureTask.get(timeoutNumber, TimeUnit.MILLISECONDS);
//} catch (InterruptedException | ExecutionException | TimeoutException e) {
//e.printStackTrace();
//futureTask.cancel(true);
} catch (Exception e) {
//log info show here...
result = "timeoutOrException";
}
return result;
}
/**
* 实际含具体的业务逻辑工作的方法,
* @param productParam
* @return
*/
@Transactional
public String realUpdateInfo(Product productParam) {
//此处真正执行业务方法的时间不确定,
//但却是一连串完整的业务流程操作,无返回或返回的结果可以不理
//real buiz code go here...
return null;
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
欢迎拍砖讨论...
推荐阅读
-
多线程使用解决并带主动超时的问题
-
在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决思路详解
-
Python使用urllib模块的urlopen超时问题解决方法
-
Python使用urllib模块的urlopen超时问题解决方法
-
Linux下PureFtpd的基本安装使用与超时问题解决
-
使用NDKr9c编译安卓项目并打包时遇到的问题及解决办法
-
C#使用读写锁三行代码简单解决多线程并发的问题
-
关于使用maven + Tomcat7-maven-plugin管理并运行web项目抛出cannot be cast to javax.servlet.Servlet的问题和解决
-
maven项目添加lombok并解决使用@data注解无set/get方法的问题
-
Window 10 Google Chrome无法启动更新检查(错误代码为1)- 卸载重装chrome并使用mklink解决chrome安装在其他盘的问题