Mad*_*sen 11 java multithreading future
我想第一次使用期货.你可以取消一份工作似乎很聪明,但它没有按预期工作.在下面的示例中,仅取消第一个作业.其余的都完成了.我误解了期货的使用吗?
public class ThreadExample
{
public static void main(String[] args) throws InterruptedException, ExecutionException
{
int processors = Runtime.getRuntime().availableProcessors();
System.out.println("Processors: " + processors);
ExecutorService es = Executors.newFixedThreadPool(processors);
int nowork = 10;
Future<Integer>[] workres = new Future[nowork];
for(int i = 0; i < nowork; i++)
{
workres[i] = es.submit(new SomeWork(i));
}
for(int i = 0; i < nowork; i++)
{
if(i % 2 == 0)
{
System.out.println("Cancel");
workres[i].cancel(true);
}
if(workres[i].isCancelled())
{
System.out.println(workres[i] + " is cancelled");
}
else
{
System.out.println(workres[i].get());
}
}
es.shutdown();
}
}
class SomeWork implements Callable<Integer>
{
private int v;
public SomeWork(int v)
{
this.v = v;
}
@Override
public Integer call() throws Exception
{
TimeUnit.SECONDS.sleep(5);
System.out.println(v + " done at " + (new Date()));
return v;
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
Processors: 4
Cancel
java.util.concurrent.FutureTask@10d448 is cancelled
4 done at Wed May 12 17:47:05 CEST 2010
2 done at Wed May 12 17:47:05 CEST 2010
1 done at Wed May 12 17:47:05 CEST 2010
3 done at Wed May 12 17:47:05 CEST 2010
1
Cancel
2
3
Cancel
4
5 done at Wed May 12 17:47:10 CEST 2010
7 done at Wed May 12 17:47:10 CEST 2010
8 done at Wed May 12 17:47:10 CEST 2010
6 done at Wed May 12 17:47:10 CEST 2010
5
Cancel
6
7
Cancel
8
9 done at Wed May 12 17:47:15 CEST 2010
9
Run Code Online (Sandbox Code Playgroud)
该Future#cancel()不会终止/中断已经运行的作业.它只会取消尚未运行的工作.
更新:polygenelubricants确定根本原因(+1):这是改进的代码:
int processors = Runtime.getRuntime().availableProcessors();
System.out.println("Processors: " + processors);
ExecutorService es = Executors.newFixedThreadPool(processors);
int nowork = 10;
Future<Integer>[] workers = new Future[nowork];
for (int i = 0; i < nowork; i++) {
final int ii = i;
workers[i] = es.submit(new Callable<Integer>() {
public Integer call() throws Exception {
return ii;
}
});
}
for (int i = 0; i < nowork; i++) {
if (i % 2 == 0) {
System.out.println("Cancel worker " + i);
workers[i].cancel(true);
}
}
for (int i = 0; i < nowork; i++) {
if (workers[i].isCancelled()) {
System.out.println("Worker " + i + " is cancelled");
} else {
System.out.println("Worker " + i + " returned: " + workers[i].get());
}
}
es.shutdown();
Run Code Online (Sandbox Code Playgroud)
结果:
Processors: 2 Cancel worker 0 Cancel worker 2 Cancel worker 4 Cancel worker 6 Cancel worker 8 Worker 0 is cancelled Worker 1 returned: 1 Worker 2 is cancelled Worker 3 returned: 3 Worker 4 is cancelled Worker 5 returned: 5 Worker 6 is cancelled Worker 7 returned: 7 Worker 8 is cancelled Worker 9 returned: 9
(请注意workers,不是workres).
问题是你的取消循环与你的get()循环重叠,这会阻塞.我想你想要2个循环,不是吗?一个循环取消偶数编号的作业,然后是第二个循环,检查哪些被取消,哪些不被取消,然后get()相应地.
它现在的方式,在循环甚至有机会取消之前workres[2],它检查并要求get()从workres[1].
所以我认为你需要3个阶段:
1. The `submit()` loop
2. The selective `cancel()` loop
3. The selective `get()` loop (which blocks)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3750 次 |
| 最近记录: |