The correct way to submit and wait for the ExecutorService to terminate

I am studying using thread pools in Java with ExecutorService, here is an example I'm working on:

public class Example {
    static class WorkerThread implements Runnable {
        private String command;

        public WorkerThread(String s) {
            this.command = s;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
            processCommand();
            System.out.println(Thread.currentThread().getName() + " End.");
        }

        private void processCommand() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            return this.command;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 10; i++) {
            Runnable worker = new WorkerThread("" + i);
            executor.execute(worker);
        }
        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.SECONDS);
//        while (!executor.isTerminated()) {
//        }
        System.out.println("Finished all threads");
    }
}

I have two questions:

  • How do I wait for an ending ExecutorService, should I use awaitTermination()or isTerminated()(it has been suggested that the latter is the wrong way to do this)?

  • Is it added Runnableto the executor correctly, or should I use it submit()with the callback Future<T>?

This probably depends on the context, so please explain (for both questions) when I should use each of the solutions mentioned.

+4
3

: (a) awaitTermination(long someTime, TimeUnit ....) while (!executor.isTerminated()). (b) Collection executor.invokeAll(....). .

+1

, JVM : , :

pool-1-thread-1 Start. Command = 0
pool-1-thread-2 Start. Command = 1
pool-1-thread-3 Start. Command = 2
pool-1-thread-4 Start. Command = 3
pool-1-thread-5 Start. Command = 4
Finished all threads
pool-1-thread-2 End.
pool-1-thread-1 End.
pool-1-thread-4 End.
pool-1-thread-1 Start. Command = 5
pool-1-thread-3 End.
pool-1-thread-2 Start. Command = 7
pool-1-thread-5 End.
pool-1-thread-4 Start. Command = 6
pool-1-thread-5 Start. Command = 9
pool-1-thread-3 Start. Command = 8
pool-1-thread-3 End.
pool-1-thread-5 End.
pool-1-thread-4 End.
pool-1-thread-1 End.
pool-1-thread-2 End.

, Finished all threads . , :

public class Example {
    static class WorkerThread implements Runnable {
        private String command;

        public WorkerThread(String s) {
            this.command = s;
        }

        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
            processCommand();
            System.out.println(Thread.currentThread().getName() + " End.");
        }

        private void processCommand() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        @Override
        public String toString() {
            return this.command;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executor = Executors.newFixedThreadPool(5);
        List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
        for (int i = 0; i < 10; i++) {
            tasks.add(Executors.callable(new WorkerThread("" + i)));
        }
        executor.invokeAll(tasks);
        System.out.println("Finished all threads");
        // this merely terminates the ExecutorService, otherwise the JVM will never close.
        executor.shutdown();
        executor.awaitTermination(10L, TimeUnit.SECONDS);

    }
}

:

pool-1-thread-1 Start. Command = 0
pool-1-thread-5 Start. Command = 4
pool-1-thread-4 Start. Command = 3
pool-1-thread-3 Start. Command = 2
pool-1-thread-2 Start. Command = 1
pool-1-thread-3 End.
pool-1-thread-1 End.
pool-1-thread-5 End.
pool-1-thread-3 Start. Command = 5
pool-1-thread-2 End.
pool-1-thread-4 End.
pool-1-thread-2 Start. Command = 8
pool-1-thread-1 Start. Command = 7
pool-1-thread-5 Start. Command = 6
pool-1-thread-4 Start. Command = 9
pool-1-thread-1 End.
pool-1-thread-4 End.
pool-1-thread-3 End.
pool-1-thread-5 End.
pool-1-thread-2 End.
Finished all threads
+1

1. ExecutorService, waitTermination() isTerminated() ( , )?

  • awaitTermination() shutdown()
  • invokeAll() -, List of Runnable/Callable tasks
  • CountDownLatch

SE :

, ExecutorService?

ExecutorService,

2. Runnables submit() Future?

  • , , Runnable
  • If you want to check the result of the task after completion, use Callable

If you use submit(), exceptions are hidden in the framework, and you need to handle the exceptions correctly.

Take a look at SE related questions:

Choose between the ExecutorService view and the ExecutorService view

difference between executor.submit and executor.execute in this code in Java?

+1
source

Source: https://habr.com/ru/post/1628189/


All Articles