如何杀死java线程?

如何杀死java线程?,java,multithreading,Java,Multithreading,我在谷歌上找到了杀死java线程的解决方案。存在两种解决方案: 立旗 使用Thread.interrupt 但这两种都不适合我。在我的线程中,我调用了一个需要很长时间才能完成的第三方api。我想让用户取消这个线程,如果它需要太多的时间 那我怎么才能杀死这根线呢?提前谢谢。你可以试试,但是。最理想的情况是,如果需要,您正在调用的API应该有一种中断操作的方法(如果API本身没有提供一种更干净的中断其进程的方法,您尝试过吗?)。Thread.interrupt()是唯一普遍适用的安全方法。当然,您可

我在谷歌上找到了杀死java线程的解决方案。存在两种解决方案:

  • 立旗
  • 使用Thread.interrupt
  • 但这两种都不适合我。在我的线程中,我调用了一个需要很长时间才能完成的第三方api。我想让用户取消这个线程,如果它需要太多的时间


    那我怎么才能杀死这根线呢?提前谢谢。

    你可以试试,但是。最理想的情况是,如果需要,您正在调用的API应该有一种中断操作的方法(如果API本身没有提供一种更干净的中断其进程的方法,您尝试过吗?)。

    Thread.interrupt()
    是唯一普遍适用的安全方法。当然,您可以使用其他应用程序级别的信号(例如对易失性变量的条件检查)来自行终止。其他方法(如所有不推荐使用的Thread.xx方法)可能会以不确定的方式污染应用程序的状态,并且需要重新加载所有应用程序状态。

    您可以在Thread对象上调用
    stop
    方法,但强烈建议不要这样做。请阅读以下内容:


    您是否有对API进行微小更改的自由?这个阻塞调用是CPU绑定的还是IO绑定的?如果它是IO绑定的,并且您有权访问底层套接字/远程通信对象,那么关闭该对象可以带来奇迹。至少比停止线程要好。

    理论上,您可以调用已弃用的
    thread.stop()
    方法。但请注意,这可能会导致应用程序以意外和不可预测的方式运行。。。这取决于第三方库实际在做什么
    Thread.stop()
    和朋友基本上是不安全的


    最好的解决方案是修改第三方库以响应Thread.interrupt。如果你做不到,那就抛弃它,找到/使用更好的库。

    生成一个单独的进程,并使用操作系统设施杀死它。您必须调用“C”来执行此操作,但代码不多。您没有说出正在运行的操作系统。

    java.util.concurrent.FutureTask中,超时取消机制被用作抛出java.util.concurrent.TimeoutException

    您可以检查这一点,就好像超时会自动中断某些内容。

    因为
    Thread.stop()
    被(正确地)弃用,通常通过将标志设置为true来实现。大概是这样的:

    主叫班级:

    ...
    workListExecutor.stop()
    ...
    
    WorkListExecutor.class:

    boolean running = true;
    
    void stop(){
      running = false;
    }
    
    void run(){
      while (running) {
        ... do my stuff ...
      }
    }
    
    这是假设您的线程有某种主循环(通常是这种情况)。 如果循环中的代码太大,您可以定期检查
    running
    是否仍然是
    true
    ,如果不是,则退出

    这样做的好处是,完成后您仍然可以进行清理。run方法完成后,线程将自动终止。

    我将把调用放在一个需要很长时间的第三方api中,
    可调用
    ,然后使用指定超时的
    SingleThreadExecutor
    执行它

    按照这种方法,如果调用第三方API的时间超过了超时时间,线程将被终止,下面是一些代码来举例说明我所说的:

    ExecutorService executor = Executors.newSingleThreadExecutor();
     try {
       //================= HERE ==================
       Future<Boolean> job = executor.submit(thirdPartyCallable);
       executor.awaitTermination(timeOut, TimeUnit.SECONDS);      
       if(!job.isDone())
         logger.debug("Long call to 3rd party API didn't finish");
       //=========================================
     } catch (Exception exc) {
         exc.printStackTrace();      
     } finally {
         if(!executor.isShutdown() )
           executor.shutdownNow();
     }
    
    }  
    
    private static Callable<Boolean>  thirdParytCallable = new Callable<Boolean>() {
      public Boolean call() throws Exception {
        //Call to long 3rd party API
        //.......
        for(long i = 0;i<99999991999999L;i++) {
          Thread.sleep(10L);// Emulates long call to 3rd party API
          System.out.print(".");
        }
        return Boolean.valueOf(true);//Data from 3rd party API
      }
    }; 
    
    ExecutorService executor=Executors.newSingleThreadExecutor();
    试一试{
    //===========================这里==================
    未来作业=执行者提交(第三方可调用);
    执行器等待终止(超时,时间单位秒);
    如果(!job.isDone())
    debug(“对第三方API的长时间调用未完成”);
    //=========================================
    }捕获(异常exc){
    exc.printStackTrace();
    }最后{
    如果(!executor.isShutdown())
    执行者。关机现在();
    }
    }  
    私有静态可调用thirdParytCallable=新可调用(){
    公共布尔调用()引发异常{
    //对第三方长API的调用
    //.......
    
    对于(long i=0;iwell,这应该行得通,但对我来说太重了,它会增加集成和共享数据的复杂性。你不需要杀死它,就让它们自杀吧……Thread.interrupt只是故事的一半,你正在中断的线程必须支持使用中断标志的中断策略……调用的就是那个标志Thread.interrupt将重置。大多数情况下,Thread.interrupt不会终止线程,而是线程继续运行。在这种情况下,什么是最佳解决方案。@Kathir:Thread.interrupt在被阻止时向线程发送InterruptedException。您的工作是捕获并适当关闭它。@YannRamin,您如何关闭i正确关闭?是的,Ramin,请详细说明?Joshua Bloch的“有效Java”第二版第68项:更喜欢执行器和任务而不是线程未来+调用该方法不允许强制停止线程。
    Future.cancel
    方法使用
    thread.interrupt()
    ,我们已经被告知
    thread.interrupt()
    不是一个解决方案。