This shows you the differences between two versions of the page.
Both sides previous revision Previous revision | |||
java_concurrency [2012/09/05 10:42] hkoller [Waiting until tasks are done] |
java_concurrency [2012/09/19 17:02] (current) hkoller [Example: Thread Pool] |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Basics ====== | ||
+ | * Thread should be seen as **deprecated** | ||
+ | |||
+ | |||
+ | ====== Executor Framework ====== | ||
+ | Java introduces the [[http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html|Executor Framework]] as a new Highlevel Mechanism to handle concurrency. | ||
+ | |||
+ | Basically this includes the following steps: | ||
+ | |||
+ | * Create a Worker classes that either implements Runnable or Callable | ||
+ | * Create Worker instances | ||
+ | * Create an ExecutorService | ||
+ | * newSingleThreadExecutor | ||
+ | * newCachedThreadPool | ||
+ | * newFixedThreadPool | ||
+ | * Submit the workers to the executor service | ||
+ | * Wait for the workers to finish | ||
+ | * Shutdown the ExecutorService | ||
+ | |||
+ | |||
+ | ===== Example: Thread Pool ===== | ||
+ | <code java> | ||
+ | public class ThreadPoolExecutorDemo { | ||
+ | |||
+ | public static void main(String[] args) throws Exception { | ||
+ | ExecutorService executor = Executors.newFixedThreadPool(2); | ||
+ | |||
+ | executor.submit(new Worker()); | ||
+ | executor.submit(new Worker()); | ||
+ | |||
+ | executor.shutdown(); | ||
+ | executor.awaitTermination(60, TimeUnit.SECONDS); // wait until finished, but at most for 60 seconds | ||
+ | |||
+ | System.out.println("Done"); | ||
+ | } | ||
+ | |||
+ | public static class Worker implements Runnable { | ||
+ | @Override | ||
+ | public void run() { | ||
+ | // do work | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | If the Worker should yield a result, implement **Callable<T>** instead of Runnable: | ||
+ | |||
+ | <code java> | ||
+ | public class ThreadPoolTest { | ||
+ | public static void main(String[] args) throws Exception { | ||
+ | ExecutorService executor = Executors.newFixedThreadPool(2); | ||
+ | |||
+ | Future<Integer> result1 = executor.submit(new Worker()); | ||
+ | Future<Integer> result2 = executor.submit(new Worker()); | ||
+ | |||
+ | System.out.println("Results: " + result1.get() + " " result2.get()); // note that get() might throw an Exception if the worker did not finish normally | ||
+ | } | ||
+ | |||
+ | public static class Worker implements Callable<Integer> { | ||
+ | @Override | ||
+ | public Integer call() { | ||
+ | int result=0; | ||
+ | // do some work | ||
+ | return result; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | |||
+ | ===== Waiting until tasks are done ===== | ||
+ | <code java> | ||
+ | |||
+ | public static void main(String[] args) throws Exception { | ||
+ | List<Worker> tasks = new ArrayList<>(); | ||
+ | |||
+ | tasks.add(new Worker()); | ||
+ | tasks.add(new Worker()); | ||
+ | |||
+ | ExecutorService executor = Executors.newFixedThreadPool(2); | ||
+ | List<Future<Integer>> results = executor.invokeAll(tasks); // blocks until all tasks are done | ||
+ | |||
+ | System.out.println("Result1: " + results.get(0).get()); | ||
+ | System.out.println("Result2: " + results.get(1).get()); | ||
+ | |||
+ | System.out.println("Done"); | ||
+ | |||
+ | executor.shutdown(); | ||
+ | } | ||
+ | |||
+ | |||
+ | public static class Worker implements Callable<Integer> { | ||
+ | ..... | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||