Java 如何检测未知线程池并将其关闭?
我需要为调用jar文件中的方法的代码块设置超时。 我正在使用以下代码Java 如何检测未知线程池并将其关闭?,java,multithreading,Java,Multithreading,我需要为调用jar文件中的方法的代码块设置超时。 我正在使用以下代码 final Runnable stuffToDo = new Runnable() { @Override public void run() { /* Do stuff here. */ jarclass.run(); } }; final ExecutorService executor
final Runnable stuffToDo = new Runnable() {
@Override
public void run() {
/* Do stuff here. */
jarclass.run();
}
};
final ExecutorService executor = Executors.newFixedThreadPool(1);
final Future future = executor.submit(stuffToDo);
//executor.shutdown(); // This does not cancel the already-scheduled task.
try {
future.get(1, TimeUnit.SECONDS);
}
catch (InterruptedException ie) {
/* Handle the interruption. Or ignore it. */
}
catch (ExecutionException ee) {
/* Handle the error. Or ignore it. */
}
catch (TimeoutException te) {
/* Handle the timeout. Or ignore it. */
}
if (!executor.isTerminated()){
executor.shutdownNow();
}
但是,jarclass.run()以某种方式启动另一个线程,该线程继续运行,并显示池-2-thread-1的所有打印输出
如何完全关闭jarclass.run()
更新:
我将new Thread()更改为new Runnable。它仍然不起作用。
让我困惑的是,我不知道jarclass从哪里开始另一个线程,并且无法处理它。当代码转到executor.shutdownNow()时,它会跳出并运行以下代码。但是jarclass.run()仍在运行。
我的英语不是很好。希望我能说清楚
更新:
此代码解决的问题:
Future<String> future = new FutureTask<String>(new Callable<String>() {
public String call() throws Exception {
jarclass.run();
return null;
}
});
try {
future.get(1, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
Future-Future=new-FutureTask(new-Callable(){
公共字符串调用()引发异常{
jarclass.run();
返回null;
}
});
试一试{
future.get(1,TimeUnit.SECONDS);
}捕获(例外e){
e、 printStackTrace();
}
不知道以前的代码为什么会失败……如果有人知道,我们仍然可以讨论
谢谢你所有善意的回复。非常感谢。在使用
ExecutorService
时,不应实例化线程。改用Runnable
:
final Runnable stuffToDo = new Runnable() { /* as it is now */ };
当您直接创建线程时,它不是由您稍后创建的executor服务管理的,这就是为什么所有日志都是如此。直接杀死线程是不安全的,请参阅
建议使用一个可以通知线程停止时间的标志
若您可以访问jar并修改代码,那个么您可以使用标志在jarclass
中创建一个名为stop()
的方法,以便在需要终止进程时可以调用jarclass.stop()
例如:
public class jarclass{
private boolean keepAlive = true;
public void run(){
keepAlive = true;
while(keepAlive){
//do work
}
}
public void stop(){
keepAlive = false;
}
}
您可能希望直接使用线程并调用其中断方法。但我不确定这是否有效。只会阻止添加新任务,但允许已在运行的任务完成:“启动有序关机,在其中执行以前提交的任务,但不接受新任务。”您可以尝试在未来的TimeoutException上调用(中断)。顺便说一句:您不需要将Stuff设置为新线程
,newrunnable
就可以了。这可能看起来很奇怪,因为它是一个接口,但实际上您正在创建一个实现该接口的匿名类。这意味着线程应该作为池线程的子线程“可访问”。您应该能够对run方法中的中断做出反应,并尝试将中断传播到所有子线程。当父线程被中断时,子线程将被中断。但这真的很奇怪。我已经阅读了jar类中的代码,我没有找到任何新的线程…………我不能终止它……看起来像JARCuff.Run()中的所有代码都被放到另一个线程池中,并且它保持打印POOL 2-THEAD -1信息……这可能会起作用,但是我会考虑改变JARCKE作为版权问题的最后一个选项。希望我能想出其他的解决办法。但无论如何还是要谢谢你。是的,这不是一个很好的解决方案,但是如果jarclass的run()方法启动了一个新线程,而你没有任何对它们的引用,我看到了一些解决方案。我不确定run()是否启动了一个新线程。我浏览了jarclass代码,但没有找到任何新的Thread()语句。但是run()中的所有消息都使用pool-2-thread-1打印。主程序流确实跳过了jarclass.run(),但没有终止它。我不这么认为。我同意他应该使用newrunnable
,但将其传递给ExecutorService只意味着服务将使用线程的run
方法。既然他没有启动线程,它仍然可以工作。