java - Java 中用于 Futures 任务的泛型和通配符

标签 java multithreading generics concurrent.futures

public class SOQuestion {
private class TaskResult1 {//some pojo  
}

private class TaskResult2{// some other pojo 
}

private class Task1 implements Callable<TaskResult1> {
    public TaskResult1 call() throws InterruptedException {
        // do something...
        return new TaskResult1();
    }
}

private class Task2 implements Callable<TaskResult2> {
    public TaskResult2 call() throws InterruptedException {
        // do something else...
        return new TaskResult2();
    }
}

private void cancelFuturesTask1(List<Future<TaskResult1>> futureList ){
    for(Future<TaskResult1> future: futureList){
        if(future.isDone())
        {
            continue;
        } else
        {
            System.out.println("cancelling futures.....Task1.");
            future.cancel(true);
        }
    }
}

private void cancelFuturesTask2(List<Future<TaskResult2>> futureList ){
    for(Future<TaskResult2> future: futureList){
        if(future.isDone())
        {
            continue;
        } else
        {
            System.out.println("cancelling futures.....Task2.");
            future.cancel(true);
        }
    }
}

void runTasks() {
    ExecutorService executor = Executors.newFixedThreadPool(4);
    CompletionService<TaskResult1> completionService1 = new ExecutorCompletionService<TaskResult1>(executor);
    List<Future<TaskResult1>> futuresList1 = new ArrayList<Future<TaskResult1>>();

    for (int i =0 ;i<10; i++) {
        futuresList1.add(completionService1.submit(new Task1()));
    }

    for (int i = 0; i< 10; i++) {
        try {
            Future<TaskResult1> f = completionService1.take();
            System.out.print(f.get());
            System.out.println("....Completed..first one.. cancelling all others.");    
            cancelFuturesTask1(futuresList1);
        } catch (InterruptedException e) {
            System.out.println("Caught interrruption....");
            break;
        } catch (CancellationException e) {
            System.out.println("Cancellation execution....");
            break;
        } catch (ExecutionException e) {
            System.out.println("Execution exception....");
            break;
        }
    }


    CompletionService<TaskResult2> completionService2 = new ExecutorCompletionService<TaskResult2>(executor);
    List<Future<TaskResult2>> futuresList2 = new ArrayList<Future<TaskResult2>>();
    try{
        for (int i =0 ;i<10; i++) {
            futuresList2.add(completionService2.submit(new Task2()));
        }
        for (int i = 0; i< 10; i++) {
            try {
                Future<TaskResult2> f = completionService2.take();
                System.out.print(f.get());
                System.out.println("....Completed..first one.. cancelling all others.");    
                cancelFuturesTask2(futuresList2);
            } catch (InterruptedException e) {
                System.out.println("Caught interrruption....");
                break;
            } catch (CancellationException e) {
                System.out.println("Cancellation execution....");
                break;
            } catch (ExecutionException e) {
                System.out.println("Execution exception....");
                break;
            }
        }
    }catch(Exception e){

    }

    executor.shutdown();
}
}

如示例所示,存在一些重复。我想使用泛型和通配符来概括对象并重用一些方法。

我的具体要求是“cancelFuturesTask1”和“cancelFuturesTask2”。两种方法都做同样的事情。我怎样才能概括它们? 我读到了这个:https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html

我创建了一个基类“TaskResult”扩展“TaskResult1”和“TaskResult2”

private class TaskResult1 extends TaskResult
private class TaskResult2 extends TaskResult

然后使用

List<Futures<? extends TaskResult>>

这给我带来了复杂的错误,并且我在将概念扩展到List<Futures<?>>时遇到了一些困惑。在这种情况下。 任何有关如何执行此操作的指示或解释都会有所帮助。

提前致谢,如果您需要一些说明,请告诉我。

最佳答案

这对我来说编译得很好,如果您也遇到错误,请告诉我。

public class FutureTest
{

   public void cancelAll( Future<?> ... futures ) {
      for( Future<?> f : futures ) {
         if( !f.isDone() ) {
            Logger.getLogger(FutureTest.class.getName()).log(
                    Level.INFO, "Canceling {0}", f);
            f.cancel(true);
         }
      }
   }

   public <T extends Task1 & Task2> void cancelAll( List<Future<T>> futures ) {
      cancelAll( futures.toArray( new Future[futures.size()]) );
   }
}

interface Task1 {}
interface Task2 {}

更具体的类型,请看我的第二种方法。您可以使用通用方法和有界类型参数来完成此操作,但前提是除一种类型之外的所有类型都是接口(interface)。 Java 不支持多重继承,因此您无法编写一种采用多个(非协变)类类型的方法。这就是为什么我认为像第一个示例这样的无界(通配符,“<?>”)方法在这里更好。

https://docs.oracle.com/javase/tutorial/java/generics/boundedTypeParams.html

关于java - Java 中用于 Futures 任务的泛型和通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35162361/

相关文章:

c# - 从通用类调用通用事件处理程序

java - Eclipse:如何防止格式化多行连接字符串?

c++ - 如何干净地退出线程 C++ 程序?

java - 如何获取Java泛型的类对象?

c++ - 如何立即取消 curl 操作?

java - Java中的方法队列

java - 扩展可比较的泛型

java - 使用 spring 查询方法出现意外的空结果

java - Method对象相当于Command设计模式中的Command对象吗?

java - 从 JPanel 中删除透明 JPanel