我创建了一个Callable实例,并使用ExecutorService创建了一个新线程。如果线程未完成执行,我想在一段时间后终止该线程。在浏览了jdk文档之后,我意识到Future.cancel()方法可以用来停止线程的执行,但让我感到沮丧的是它没有用。当然,future.get()方法是在规定的时间(在我的情况下是2秒)之后向线程发送一个中断,甚至线程正在接收这个中断,但只有在线程完成执行后才会发生这种中断完全。但我想在2秒后杀死该线程。
任何人都可以帮我解决这个问题。
Testclass代码:
====================================
public class TestExecService {
public static void main(String[] args) {
//checkFixedThreadPool();
checkCallablePool();
}
private static void checkCallablePool()
{
PrintCallableTask task1 = new PrintCallableTask("thread1");
ExecutorService threadExecutor = Executors.newFixedThreadPool(1);
Future<String> future = threadExecutor.submit(task1);
try {
System.out.println("Started..");
System.out.println("Return VAL from thread ===>>>>>" + future.get(2, TimeUnit.SECONDS));
System.out.println("Finished!");
}
catch (InterruptedException e)
{
System.out.println("Thread got Interrupted Exception ==============================>>>>>>>>>>>>>>>>>>>>>>>>>");
//e.printStackTrace();
}
catch (ExecutionException e)
{
System.out.println("Thread got Execution Exception ==============================>>>>>>>>>>>>>>>>>>>>>>>>>");
}
catch (TimeoutException e)
{
System.out.println("Thread got TimedOut Exception ==============================>>>>>>>>>>>>>>>>>>>>>>>>>");
future.cancel(true);
}
threadExecutor.shutdownNow();
}
}
可调用类代码:
===================================================================
package com.test;
import java.util.concurrent.Callable;
public class PrintCallableTask implements Callable<String> {
private int sleepTime;
private String threadName;
public PrintCallableTask(String name)
{
threadName = name;
sleepTime = 100000;
}
@Override
public String call() throws Exception {
try {
System.out.printf("%s going to sleep for %d milliseconds.\n", threadName, sleepTime);
int i = 0;
while (i < 100000)
{
System.out.println(i++);
}
Thread.sleep(sleepTime); // put thread to sleep
System.out.printf("%s is in middle of execution \n", threadName);
} catch (InterruptedException exception) {
exception.printStackTrace();
}
System.out.printf("%s done sleeping\n", threadName);
return "success";
}
}
答案 0 :(得分:8)
您的代码可以正常运行。唯一的问题是您没有在Thread.isInterrupted
循环中检查while
。线程获取消息的唯一方法是进入阻塞调用Thread.sleep
,这将立即抛出InterruptedException
。
如果循环很长,可能需要一些时间。这正是您的代码有点无响应的原因。
检查中断状态,例如,每10,000次迭代:
while (i < 100000) {
if (i % 10000 == 0 && Thread.currentThread().isInterrupted())
return "fail";
System.out.println(i++);
}
InterruptedException
用于冗长的阻止方法。 Thread.isInterrupted
用于其他一切。
答案 1 :(得分:4)
cancel()
只是为已经执行的线程调用interrupt()
。
http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html:
中断是一个线程的指示,它应该停止它 正在做并做其他事情。这取决于程序员的决定 线程如何响应中断,但这很常见 让线程终止。
中断的线程只会抛出InterruptedException
当线程正在等待,休眠或以其他方式暂停一段时间 时间和另一个线程使用interrupt()方法中断它 class Thread。
因此,您需要在执行线程时明确地生成作业代码,以了解可能的中断。
另见Who is calling the Java Thread interrupt() method if I'm not?。
另请参阅How to cancel Java 8 completable future?,因为Java期货仅由Java 8成熟。