Java中线程池中断子线程的问题。有代码,有经验的来看看。

Justflyaway 2013-02-06 09:59:58
如下代码为应用的一个模型,当超时时,futureTask.cancel(true)是没有对该task进行中断的,而死循环一直在不停的执行不停的执行。。。。。

求解决方案,已经折腾了一天了,对明天回家过年都没什么兴奋点了。

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class Test3 {

private static String testResult(int num) {
System.out.println("begin");
if (1 == num) {
while (true) {
System.out.println("test");
}
} else {
return "12333";
}
}

public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
FutureTask<String> futureTask = new FutureTask<String>(
new Callable<String>() {
public String call() {

return testResult(1);
}
});

executor.execute(futureTask);

String result = null;
try {

result = futureTask.get(100, TimeUnit.MILLISECONDS);

} catch (InterruptedException e) {
futureTask.cancel(true);
} catch (ExecutionException e) {
futureTask.cancel(true);
} catch (TimeoutException e) {
futureTask.cancel(true);
} finally {
System.out.println("closing...");
executor.shutdown();
System.out.println("closd.");
}
System.out.println("result=" + result);
}

}
...全文
645 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
EM265 2014-03-14
  • 打赏
  • 举报
回复
上面的我回答错了,见笑了,罪过罪过
EM265 2014-03-14
  • 打赏
  • 举报
回复
引用 10 楼 Justflyaway 的回复:
[quote=引用 7 楼 bluemoby 的回复:] 理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的结果。最好是在所谓的第三方代码中加入中断判断的逻辑。
我又做了2个实验: 如下代码可以终止,但是无法使用线程池。。。。。。
thread = new Thread(futureTask);
thread.start();

try {
	//exec.execute(thread);
	thread.start();
	result=task.get(timeLimit,TimeUnit.MILLISECONDS);	
} catch (TimeoutException e) {
	
	thread.stop();
}
如下代码使用了线程池,但是通过线程池执行以后,stop操作会失效:
thread = new Thread(futureTask);
exec.execute(thread);//exec是newSingleThreadExecutor

try {
	
	thread.start();
	result=task.get(timeLimit,TimeUnit.MILLISECONDS);	
} catch (TimeoutException e) {
	
	thread.stop();
}
求指点,求解脱……[/quote] 将线程池中thread.stop();改中Thread.currentThread().stop();试试!
dracularking 2013-02-08
  • 打赏
  • 举报
回复
引用 3 楼 Justflyaway 的回复:
谢谢指点,昨天后半夜的时候去stackoverflow也找到了这个关于cancel的解释,调用的是线程的interrupte(); 但是现在的需求,线程中运行的是第三方代码,是不可控的,有可能里边有死循环,但是使用线程池又没有类似thread.stop的函数,请问有没有什么办法强制终止futureTask?
对于非妥善实现的线程而要强行终止的话可能也只有你所提到过的不计后果的stop方法了 线程池中无法stop?没试过,觉得应该不存在区别才对或者存在换一种形式的相同实现,比如线程直接close之类。
龙四 2013-02-07
  • 打赏
  • 举报
回复
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 6 楼 ticmy 的回复:
别人的代码是死循环且不支持中断,靠中断是无法从中退出的
刚才回复错了人了,。。 我又做了2个实验: 如下代码可以终止,但是无法使用线程池:
thread = new Thread(futureTask);
thread.start();

try {	
	result=task.get(timeLimit,TimeUnit.MILLISECONDS);	
} catch (TimeoutException e) {
	
	thread.stop();
}
如下代码使用了线程池,但是通过线程池执行以后,stop操作会失效:

thread = new Thread(futureTask);
exec.execute(thread);//exec是newSingleThreadExecutor

try {
		result=task.get(timeLimit,TimeUnit.MILLISECONDS);	
} catch (TimeoutException e) {
	
	thread.stop();
}
楼上刚贴的代码有误,重新贴一次
  • 打赏
  • 举报
回复
回复有限制了,,,小号插个楼。。。。
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 7 楼 bluemoby 的回复:
理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的结果。最好是在所谓的第三方代码中加入中断判断的逻辑。
我又做了2个实验: 如下代码可以终止,但是无法使用线程池。。。。。。
thread = new Thread(futureTask);
thread.start();

try {
	//exec.execute(thread);
	thread.start();
	result=task.get(timeLimit,TimeUnit.MILLISECONDS);	
} catch (TimeoutException e) {
	
	thread.stop();
}
如下代码使用了线程池,但是通过线程池执行以后,stop操作会失效:
thread = new Thread(futureTask);
exec.execute(thread);//exec是newSingleThreadExecutor

try {
	
	thread.start();
	result=task.get(timeLimit,TimeUnit.MILLISECONDS);	
} catch (TimeoutException e) {
	
	thread.stop();
}
求指点,求解脱……
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 7 楼 bluemoby 的回复:
理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的结果。最好是在所谓的第三方代码中加入中断判断的逻辑。
第三方代码是开放提交的,编译以后进行运行……所以第三方代码不可能有任何限制……哎……
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 6 楼 ticmy 的回复:
别人的代码是死循环且不支持中断,靠中断是无法从中退出的
如果靠中断无法退出有没有强制中断task的方法???
bluemoby 2013-02-07
  • 打赏
  • 举报
回复
理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的结果。最好是在所谓的第三方代码中加入中断判断的逻辑。
龙四 2013-02-07
  • 打赏
  • 举报
回复
别人的代码是死循环且不支持中断,靠中断是无法从中退出的
龙四 2013-02-07
  • 打赏
  • 举报
回复
http://ifeve.com/cancellation/#interruption 如果你的代码调用了其它未正确维持中断状态的代码(例如,忽略InterruptedException又不重设状态),可以能通过维持一个字段来规避问题,这个字段用于保存活动取消的标识,在调用interrupt的时候设置该字段,从有问题的调用中返回时检查该字段
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 2 楼 bluemoby 的回复:
futureTask.cancel方法会中断执行此任务的线程,中断的方法是调用对应线程的interrupt()方法,interrupt方法只是简单的设置中断标志位。你的循环里面既没有检测循环的中断标志位,也没有在循环内部调用sleep或await方法,所以程序无法判断你的线程已经中断。修改的方法是在循环处加入中断标志位的检测语句,将 while (true) { ……
task中的代码是不可控的,已经用securitymanager限制了权限,但是还是没办法限制死循环。。。能否强制终止task?
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 1 楼 dracularking 的回复:
做了下实验,初步认为while(true)循环是属于无法被中断的那一类中的,如果没有while(true),则可以被cancel javadoc也对这种现象预留了解释空间: Attempts to cancel execution of this task. This attempt will fail if the task has already comple……
谢谢指点,昨天后半夜的时候去stackoverflow也找到了这个关于cancel的解释,调用的是线程的interrupte(); 但是现在的需求,线程中运行的是第三方代码,是不可控的,有可能里边有死循环,但是使用线程池又没有类似thread.stop的函数,请问有没有什么办法强制终止futureTask?
bluemoby 2013-02-07
  • 打赏
  • 举报
回复
引用 16 楼 Justflyaway 的回复:
引用 14 楼 bluemoby 的回复:引用 10 楼 Justflyaway 的回复:引用 7 楼 bluemoby 的回复:理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的……
你的例子中你是把thread当作简单的runnable接口使用,线程池启动自己的线程,调用thread的run方法,然后thread的run方法直接调用futureTask的方法。
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 14 楼 bluemoby 的回复:
引用 10 楼 Justflyaway 的回复:引用 7 楼 bluemoby 的回复:理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的结果。最好是在所谓的第三方代码中加入中断判……
通过线程池start的。。。我明天有空看看源代码吧~
Justflyaway 2013-02-07
  • 打赏
  • 举报
回复
引用 13 楼 ticmy 的回复:
stop存在的一些问题:http://ifeve.com/cancellation/#asyntermination
我知道stop有问题,,,但是不用stop真的没办法停止了。 而且现在stop对于线程池中的线程也无效。 有没有什么好点子指点一下?
bluemoby 2013-02-07
  • 打赏
  • 举报
回复
引用 10 楼 Justflyaway 的回复:
引用 7 楼 bluemoby 的回复:理论上可以实现中断,不过比较麻烦,需要你继承FutureTask,在里面定义一个中断方法,在这个新定义的中断方法中,调用对应线程的stop方法。不过不推荐这么做,stop方法已经不推荐使用了,因为强行中断线程可能造成数据的不一致,导致难以预料的结果。最好是在所谓的第三方代码中加入中断判断的逻辑。 我又做了2个实验: 如下代码……
你的第二段代码中,thread对象根本就没start,所以使用stop也没有什么用,实际在运行的是exec线程池中的线程。使用线程池好像没有办法直接获取到运行代码的线程,所以你还是想别的办法吧。
bluemoby 2013-02-06
  • 打赏
  • 举报
回复
futureTask.cancel方法会中断执行此任务的线程,中断的方法是调用对应线程的interrupt()方法,interrupt方法只是简单的设置中断标志位。你的循环里面既没有检测循环的中断标志位,也没有在循环内部调用sleep或await方法,所以程序无法判断你的线程已经中断。修改的方法是在循环处加入中断标志位的检测语句,将 while (true) { System.out.println("test"); } 修改为 while (!Thread.currentThread().isInterrupted()) { System.out.println("test"); }
dracularking 2013-02-06
  • 打赏
  • 举报
回复
做了下实验,初步认为while(true)循环是属于无法被中断的那一类中的,如果没有while(true),则可以被cancel javadoc也对这种现象预留了解释空间: Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. 从原理上讲,可能在某些不应该被中断的场合如果强行中断的话,会使某些对象或其它什么状态不一致,可能是出于这种担心吧~ http://stackoverflow.com/questions/6969978/futuretask-cancel

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧