Java并发性:在任务池中查找任务失败
下面显示了从服务器获取记录(例如)Java并发性:在任务池中查找任务失败,java,multithreading,concurrency,Java,Multithreading,Concurrency,下面显示了从服务器获取记录(例如)ExecutorService用于创建一个由2个线程组成的ThreadPool,我已经用3秒的Timeout调用了所有这些线程。 我故意让一些任务失败 现在我的问题是,如何获取失败任务的EmpID? 主要类别: public class MultiThreadEx { public static void main(String[] args) { String[] empIDArray = { "100
ExecutorService
用于创建一个由2个线程组成的ThreadPool
,我已经用3秒的Timeout
调用了所有这些线程。
我故意让一些任务失败
现在我的问题是,如何获取失败任务的EmpID?
主要类别:
public class MultiThreadEx {
public static void main(String[] args) {
String[] empIDArray = {
"100", "200", "300", "400", "500",
"600", "700", "800", "900", "1000",
"1100", "1200", "1300", "1400", "1500"
};
List<ThreadTaskEach> taskList = new ArrayList<ThreadTaskEach>();
try {
for(String empID : empIDArray) {
taskList.add(new ThreadTaskEach(empID));
}
} catch(Exception e) {
System.out.println("Exception occured: " + e.getMessage());
}
List<Future<Map<String, String>>> futureList = null;
try {
ExecutorService service = Executors.newFixedThreadPool(2);
futureList = service.invokeAll(taskList, 3, TimeUnit.SECONDS);
service.shutdown();
} catch(InterruptedException ie) {
System.out.println("Exception occured: " + ie.getMessage());
}
for(Future<Map<String, String>> future : futureList) {
try {
Map<String, String> resultMap = future.get();
for(String key : resultMap.keySet()) {
System.out.println(resultMap.get(key));
}
} catch(ExecutionException ee) {
System.out.println("Exception occured: " + ee.getMessage());
} catch (InterruptedException ie) {
System.out.println("Exception occured: " + ie.getMessage());
} catch(CancellationException e) {
System.out.println("Exception occured: " + e.getMessage());
}
}
}
}
公共类多线程{
公共静态void main(字符串[]args){
字符串[]empidaray={
"100", "200", "300", "400", "500",
"600", "700", "800", "900", "1000",
"1100", "1200", "1300", "1400", "1500"
};
List taskList=new ArrayList();
试一试{
for(字符串empID:empidaray){
taskList.add(newthreadtaskeach(empID));
}
}捕获(例外e){
System.out.println(“发生异常:+e.getMessage());
}
List futureList=null;
试一试{
ExecutorService=Executors.newFixedThreadPool(2);
futureList=service.invokeAll(任务列表,3,时间单位:秒);
service.shutdown();
}捕获(中断异常ie){
System.out.println(“发生异常:+ie.getMessage());
}
for(未来:未来列表){
试一试{
Map resultMap=future.get();
for(字符串键:resultMap.keySet()){
System.out.println(resultMap.get(key));
}
}捕获(被执行者){
System.out.println(“发生异常:+ee.getMessage());
}捕获(中断异常ie){
System.out.println(“发生异常:+ie.getMessage());
}捕获(取消异常e){
System.out.println(“发生异常:+e.getMessage());
}
}
}
}
螺纹类
class ThreadTaskEach implements Callable<Map<String, String>>{
private String empID;
public ThreadTaskEach(String empID) {
this.empID = empID;
}
@Override
public Map<String, String> call() throws Exception {
try {
return prepareMap(empID);
} catch(Exception e) {
System.out.println("Exception occured: " + e.getMessage());
throw new Exception("Exception occured: " + e.getMessage());
}
}
private Map<String, String> prepareMap(String empID) throws InterruptedException {
Map<String, String> map = new HashMap<String, String>();
if(Integer.parseInt(empID) % 500 == 0) {
Thread.sleep(5000);
}
map.put(empID, empID + ": " + Thread.currentThread().getId());
return map;
}
}
class ThreadTaskEach实现可调用{
私有字符串empID;
公共ThreadTaskEach(字符串empID){
this.empID=empID;
}
@凌驾
公共映射调用()引发异常{
试一试{
返回准备映射(empID);
}捕获(例外e){
System.out.println(“发生异常:+e.getMessage());
抛出新异常(“发生异常:+e.getMessage());
}
}
私有映射prepareMap(字符串empID)抛出InterruptedException{
Map Map=newhashmap();
if(Integer.parseInt(empID)%500==0){
睡眠(5000);
}
put(empID,empID+:“+Thread.currentThread().getId());
返回图;
}
}
在上面的代码500,1000。。未能在3秒内完成
Map<String, String> resultMap = future.get();
Map resultMap=future.get();
因此,当我对这些任务说future.get()时,我得到的是
CancellationException
。但是如何从任务中获取EmpID?您可以逐个提交每个任务,并将每个未来存储在地图中,而不是使用invokeAll
:
Future<?> f = executor.submit(task);
map.put(f, task.getId());
只要确保使用具有稳定迭代顺序的集合(ArrayList很好)。那么使用invokeAll
就是说我无法从任务中获取empID?只有submit
可以给我这个吗?@Che我是说它看起来更简单invokeAll
以与已提交任务相同的顺序返回未来。因此,您也可以这样做(即,如果第六个未来失败,它应该对应于您原始列表中的第六个任务)。不过,如果您将集合从列表更改为集合,例如,迭代顺序可能未定义,这可能会导致错误。但是submit方法没有超时rt的参数?@Che我添加了一个可能更适合您的用例的替代方法。实际上,这个方法已经起到了作用。但是我只担心abt与迭代器为给定任务列表生成的顺序相同。
据您所知,还有其他方法吗?
for (int i = 0; i < futureList.size(); i++) {
Future<Map<String, String>> future = futureList.get(i)
try {
Map<String, String> resultMap = future.get();
for(String key : resultMap.keySet()) {
System.out.println(resultMap.get(key));
}
} catch(ExecutionException ee) {
System.out.println("Exception in task " + taskList.get(i).getId());
}
}