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());
        }
    }