我使用围绕 2 线程 FixedThreadPool ExecutorService 包裹的 CompletionService 提交了一些 Future 任务,我设置然后设置一个等于提交的任务数量的循环,并使用 completionservice.take() 等待它们全部完成或失败。麻烦是偶尔它永远不会完成(但我不知道为什么)所以我将 take() 方法更改为 poll(300,Timeout.SECONDS),想法是如果一项任务需要超过 5 分钟才能完成poll 将失败,然后最终将退出循环,我可以遍历所有期货并调用 future.cancel(true) 以强制取消有问题的任务。
但是当我运行代码并且它挂起时,我看到轮询每 5 分钟连续失败一次并且没有更多任务运行,所以我假设这两个工作人员以某种方式陷入僵局并且永远不会完成,并且永远不允许启动其他任务。因为超时是 5 分钟,并且还有 1000 个任务要运行,所以打破循环所花费的时间太长,所以取消了作业。
所以我想要做的是中断/强制取消当前任务,如果没有在 5 分钟内完成,但我看不到任何方法。
此代码示例显示了我所说的简化版本
import com.jthink.jaikoz.exception.JaikozException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.*;
public class CompletionServiceTest
{
public static void main(final String[] args)
{
CompletionService<Boolean> cs = new ExecutorCompletionService<Boolean>(Executors.newFixedThreadPool(2));
Collection<Worker> tasks = new ArrayList<Worker>(10);
tasks.add(new Worker(1));
tasks.add(new Worker(2));
tasks.add(new Worker(3));
tasks.add(new Worker(4));
tasks.add(new Worker(5));
tasks.add(new Worker(6));
List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(tasks.size());
try
{
for (Callable task : tasks)
{
futures.add(cs.submit(task));
}
for (int t = 0; t < futures.size(); t++)
{
Future<Boolean> result = cs.poll(10, TimeUnit.SECONDS);
if(result==null)
{
System.out.println("Worker TimedOut:");
continue;
}
else
{
try
{
if(result.isDone() && result.get())
{
System.out.println("Worker Completed:");
}
else
{
System.out.println("Worker Failed");
}
}
catch (ExecutionException ee)
{
ee.printStackTrace();
}
}
}
}
catch (InterruptedException ie)
{
}
finally
{
//Cancel by interrupting any existing tasks currently running in Executor Service
for (Future<Boolean> f : futures)
{
f.cancel(true);
}
}
System.out.println("Done");
}
}
class Worker implements Callable<Boolean>
{
private int number;
public Worker(int number)
{
this.number=number;
}
public Boolean call()
{
if(number==3)
{
try
{
Thread.sleep(50000);
}
catch(InterruptedException tie)
{
}
}
return true;
}
}
输出
Worker Completed:
Worker Completed:
Worker Completed:
Worker Completed:
Worker Completed:
Worker TimedOut:
Done