2017-03-15 33 views
0

我需要设置一段代码的超时时间,它将调用jar文件中的方法。 我使用下面的代码如何检测未知的线程池并将其关闭?

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线程1的打印输出。

如何完全关闭jarclass.run()?

更新: 我将新线程()更改为新的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(); 
    } 

不知道为什么以前的代码失败......如果有谁知道,我们仍然可以商量。

非常感谢您的回复。真的很感激它。

+0

您可能要直接使用一个线程,并调用其*中断*方法。但我不确定这是否会奏效。 – GhostCat

+0

['shutdown'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#shutdown--)只会阻止添加新任务,但允许已经运行的任务完成:“启动一个有序关闭,其中执行先前提交的任务,但不会接受任何新任务。”您可以尝试调用['cancel'](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html#cancel-boolean-)(中断)未来在TimeoutException。 – Fildor

+0

顺便说一句:你不需要做stuffToDo一个'新的线程','新的Runnable'会做。这看起来很奇怪,因为它是一个接口,但实际上你正在创建一个实现接口的匿名类。 – Fildor

回答

0

使用ExecutorService时,您不应该实例化Thread。使用Runnable代替:

final Runnable stuffToDo = new Runnable() { /* as it is now */ }; 

当你创建一个线程,直接,它不是由你以后创建执行服务管理的,这就是为什么所有的日志。

+0

我不这么认为。我同意他应该使用'new Runnable',但将它传递给ExecutorService意味着Service将使用Thread的'run'方法。由于他不启动线程,它仍然可以工作。 – Fildor

0

这不是安全杀死线程直接看到Thread.stop() deprecated

Recomended方式,它使用一个标志,可以通知到线程是时候停止。

如果可以访问JAR和修改代码,你可以创建一个标志使用,所以当你需要杀死过程中,你可以调用jarclass.stop()命名为您jarclassstop()方法。

例如:

public class jarclass{ 

    private boolean keepAlive = true; 

    public void run(){ 

    keepAlive = true; 
    while(keepAlive){ 
     //do work 
    } 
    } 

    public void stop(){ 
    keepAlive = false; 
    } 
} 
+0

这可能会起作用,但由于某些版权问题,我会考虑更改jarclass作为最后一个选项。希望我能想出其他解决方案。不过谢谢。 – user1703532

+0

是不是一个很好的解决方案,但如果方法run()jarclass启动一个新的线程,你没有任何引用,我看到一些解决方案 –

+0

我不确定run()是否已经开始一个新的线程或不。我通过jarclass代码,但没有找到任何新的Thread()语句。但run()中的所有消息都是使用pool-2-thread-1打印的。主程序流程跳过了jarclass.run(),但没有终止它。 – user1703532