在ExecutorService任务中停止无限循环

import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; class Task implements Callable { public String call() throws Exception { String s = "initial"; try { System.out.println("Started.."); /*for (int i=0;i<10000;i++) { if (i % 2 == 0) { System.out.println("Even"); } }*/ boolean flag = true; while(flag) { } System.out.println("Finished!"); s = "Done"; } catch (RuntimeException e) { s = "RuntimeException"; } catch (Exception e) { s = "Exception"; } finally { } return s; } } public class ExecutorServiceTest { public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); List<Future> result = executor.invokeAll(Arrays.asList(new Task()), 5, TimeUnit.SECONDS); executor.shutdown(); Iterator<Future> iter = result.iterator(); while (iter.hasNext()) { System.out.println("Came here"); Future fut = iter.next(); System.out.println(fut.get()); } } } 

有没有办法让我可以阻止线程执行无限循环?

是的,您可以使用!Thread.currentThread().isInterrupted()替换flag (或逻辑&& !Thread.currentThread().isInterrupted()

这样,当任务被取消时,循环将被终止。

循环看起来像这样:

 while(!Thread.currentThread().isInterrupted() && flag) { /* Do work. */ } 

使用应该是这样的:

 ExecutorService executor = Executors.newSingleThreadExecutor(); Future task = executor.submit(new Task()); String str; try { str = task.get(5, TimeUnit.SECONDS); } finally { task.cancel(true); } 

考虑使用synchronized (this) { this.wait() }而不是在call()内部进行sleep ,然后在外部设置布尔flag (可能直接或通过flag()方法;使用直接访问确保您的标志变量是volatile )调用task.notifyAll()来唤醒睡眠线程(确保你的任务对象是一个局部变量而不是匿名,这样你就可以调用它上面的方法,并在一个Task中使一个类属性成为标志)。

它也会更高效,因为循环浪费周期不必要 – 确切的机制被称为’保护块’( http://java.sun.com/docs/books/tutorial/essential/concurrency/guardmeth.html )。 当您从等待中醒来时,测试标志变量只是为了确保它已设置。

编辑:更仔细地查看原始问题,并使用现有的代码和原则创建一个示例(有一种方法可以使猫皮肤:) :)。 试试这个 – 这里的循环由于当前线程的中断状态而退出,该状态由于超时而被取消:

 package ett; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; class Task implements Callable { public String call() throws Exception { String s = "initial"; System.out.println("Started.."); for (int i=0;;i++) { if (i % 2 == 0) { System.out.println("Even"); } Thread.yield(); if (Thread.interrupted()) break; } System.out.println("Finished!"); s = "Done"; return s; } } public class ExecutorServiceTest { public static void main(String[] args) throws Exception { ExecutorService executor = Executors.newSingleThreadExecutor(); List> result = executor.invokeAll(Arrays.asList(new Task()), 1, TimeUnit.SECONDS); executor.shutdown(); System.out.println("came here"); for (Future f : result) { try { System.out.println(f.get()); } catch (CancellationException e) { e.printStackTrace(); } } } }