简体   繁体   English

Future.cancel()方法不起作用

[英]Future.cancel() method is not working

The code that I have creates a Callable instance and using ExecutorService a new thread is being created. 我创建了一个Callable实例,并使用ExecutorService创建了一个新线程。 I want to kill this thread after certain amount of time if the thread is not done with its execution. 如果线程未完成执行,我想在一段时间后终止该线程。 After going through the jdk documentation I've realized that Future.cancel() method can be used to stop the execution of the thread, but to my dismay its not working. 在浏览了jdk文档之后,我意识到Future.cancel()方法可以用来停止线程的执行,但让我感到沮丧的是它没有用。 Of course future.get() method is sending an interrupt to the Thread after the stipulated time (in my case its 2 seconds) and even the thread is receiving this interrupt but this interruption is taking place only once the thread is done with its execution completely. 当然,future.get()方法是在规定的时间(在我的情况下是2秒)之后向线程发送一个中断,甚至线程正在接收这个中断,但只有在线程完成执行后才会发生这种中断完全。 But I want to kill the thread after 2 seconds. 但我想在2秒后杀死线程。

Could anyone help me how to achieve this. 任何人都可以帮助我如何实现这一目标。

Testclass code: 测试类代码:

====================================

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();

      }
}

Callable Class code: 可调用的类代码:

===================================================================
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";
    }

}

Your code does everything right. 你的代码做的一切正确。 The only problem is that you're not checking Thread.isInterrupted in the while loop. 唯一的问题是你没有在while循环中检查Thread.isInterrupted The only way for thread to get the message is to get to the blocking call Thread.sleep which will immediately throw InterruptedException . 线程获取消息的唯一方法是进入阻塞调用Thread.sleep ,它将立即抛出InterruptedException If loop is lengthy it can take some time. 如果循环很长,可能需要一些时间。 That's exactly why your code is a little bit unresponsive. 这正是您的代码有点无响应的原因。

Check for interruption status, say, every 10,000 iterations: 检查中断状态,例如,每10,000次迭代:

while (i < 100000) {

    if (i % 10000 == 0 && Thread.currentThread().isInterrupted())
        return "fail";

    System.out.println(i++);
}

InterruptedException is for lengthy blocking methods. InterruptedException用于冗长的阻塞方法。 Thread.isInterrupted is for everything else. Thread.isInterrupted用于其他一切。

cancel() just calls interrupt() for already executing thread. cancel()只调用已执行线程的interrupt()

http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html : http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html

An interrupt is an indication to a thread that it should stop what it is doing and do something else. 中断是一个线程的指示,它应该停止正在做的事情并做其他事情。 It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate. 由程序员决定线程如何响应中断,但线程终止是很常见的。

Interrupted thread would throw InterruptedException only 中断的线程只会抛出InterruptedException

when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt() method in class Thread. 当一个线程正在等待,休眠或以其他方式暂停很长一段时间,另一个线程使用Thread类中的interrupt()方法中断它。

So you need to explicitly make job code in executing thread aware of possible interruption. 因此,您需要在执行线程时明确地生成作业代码,以了解可能的中断。

See also Who is calling the Java Thread interrupt() method if I'm not? 如果我不是,请参阅谁正在调用Java Thread interrupt()方法? .

See also How to cancel Java 8 completable future? 另请参见如何取消Java 8可完成的未来? as java futures matured only by Java 8. 因为java期货只有Java 8才能成熟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM