0

I'm new to Java concurrent package and want to try ExecutorService to control the execution time of a thread.

So for a keep running thread MyThread, I want to use ExecutorService and Future class to stop it after 2 seconds.

public class MyThread extends Thread {

    public static int count = 0;

    @Override
    public void run() {
        while (true) {
            System.out.println(count++);
        }
    }
}


public static void main(String[] args) throws IOException, InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(1);  
    MyThread thread = new MyThread();
    FutureTask<String> futureTask = new FutureTask<String>(thread, "success");
    try {
        executorService.submit(futureTask).get(2, TimeUnit.SECONDS);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ExecutionException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (TimeoutException e) {
        System.out.println("timeout");
        e.printStackTrace();
        executorService.shutdownNow();
    }
}

However, the thread is still keep printing numbers after 2 seconds. How can I control the thread without changing MyThread class itself?

Freya Ren
  • 2,086
  • 6
  • 29
  • 39

2 Answers2

0

Use returned Future object for control.

rkosegi
  • 14,165
  • 5
  • 50
  • 83
0

The main purpose of using ExecutorService is to hide how threads are created, reused and in general managed for the programmer.

Instead of creating MyThread, you need to implement a Runnable:

public class MyRunnable implements Runnable {
  private int count = 0;
  public void run() {
    while (true) {
      System.out.println(count++);
    }
  }
}

And, this would be how to use it:

Future<Void> f = executorService.submit(new MyRunnable());
f.get(2, TimeUnit.SECONDS);

Regarding the termination property in the question, the example Runnable is not a good one, because it does not provide an interruptible task. For example, if a sleep operation is added:

public class MyRunnable implements Runnable {
  private int count = 0;
  public void run() {
    while (!Thread.currentThread().isInterrupted()) {
      System.out.println(count++);
      try {
        Thread.sleep(0, 1);
      } catch (InterruptedException x) {
        return;
      }
    }
  }
}
Community
  • 1
  • 1
nobeh
  • 9,784
  • 10
  • 49
  • 66
  • Thread implements Runnable. I also tried your method, Future f = executorService.submit(new MyRunnable()); f.get(2, TimeUnit.SECONDS); It still not work. The thread is still running all the time. – Freya Ren Jan 21 '16 at 07:20
  • Maybe it's good to read a bit about the difference: http://stackoverflow.com/questions/541487/implements-runnable-vs-extends-thread – nobeh Jan 21 '16 at 07:54
  • In addition, you cannot *always* assume that every thread is *interruptible*. You need to ensure certain properties to allow a thread to be interrupted. That's why you see the behavior you explained. Read more at http://stackoverflow.com/questions/18702482/ensure-that-a-task-is-interruptible – nobeh Jan 21 '16 at 07:56
  • Actually, I use MyThread and change the loop while(true) to while(!Thread.currentThread().isInterrupted()). Then the thread can be interrupted. I guess unless there's a label to check thread isInterruped, the thread cannot be stopped. Thanks @nobeh – Freya Ren Jan 21 '16 at 19:15