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/