Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
469 views
in Technique[技术] by (71.8m points)

multithreading - java Fork/Join pool, ExecutorService and CountDownLatch

We have three different multi threading techniques in java - Fork/Join pool, Executor Service & CountDownLatch

Fork/Join pool (http://www.javacodegeeks.com/2011/02/java-forkjoin-parallel-programming.html)

The Fork/Join framework is designed to make divide-and-conquer algorithms easy to parallelize. That type of algorithms is perfect for problems that can be divided into two or more sub-problems of the same type. They use recursion to break down the problem to simple tasks until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem

ExecutorService is an interface that extends Executor class and represents an asynchronous execution. It provides us mechanisms to manage the end and detect progress of the asynchronous tasks.

invokeAll() : Executes the given tasks, returning a list of Futures holding their status and results when all complete. Future.isDone() is true for each element of the returned list.

CountDownLatch:(http://examples.javacodegeeks.com/core-java/util/concurrent/countdownlatch-concurrent/java-util-concurrent-countdownlatch-example/)

CountDownLatch is used in synchronisation to allow one or more threads to wait until a set of operations being performed in other threads completes.

My assumption:

In both these alternatives, final result will be known only after completion of all tasks/threads.

Are these three alternatives complimentary or supplementary to each other?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After research on various multi threading frameworks for past 3 months , I have found answer to question.

ExecutorService

It is simple and easy to use with limited control. You can use it

  1. To start parallel independent tasks with out Waiting
  2. Wait for completion of all your tasks

I prefer this one when number of Callable/Runnable tasks are small in number and piling of tasks in unbounded queue does not cause pile-up in memory & degrade the performance of the system.

It hides low level details of ThreadPoolExecutor. It does not allow playing with other parameters ( Bounded Queue, Rejection Handler etc. to fine tune the performance) as in ThreadPoolExectuor.

ThreadPoolExecutor

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)

It provides more control to you. Apart from setting minimum and maximum threads, you can set queue size and make BlockingQueue is bounded.

You can come up with your own thread factory if you need below features

  1. To set a more descriptive thread name
  2. To set thread daemon status
  3. To set thread priority

If your application is constrained by number of pending Runnable/Callable tasks, you will use bounded queue by setting the max capacity. Once the queue reaches maximum capacity, you can define RejectionHandler. Java provides four types of Rejection Handler policies.

  1. In the default ThreadPoolExecutor.AbortPolicy, the handler throws a runtime RejectedExecutionException upon rejection.

  2. In ThreadPoolExecutor.CallerRunsPolicy, the thread that invokes execute itself runs the task. This provides a simple feedback control mechanism that will slow down the rate that new tasks are submitted.

  3. In ThreadPoolExecutor.DiscardPolicy, a task that cannot be executed is simply dropped.

  4. In ThreadPoolExecutor.DiscardOldestPolicy, if the executor is not shut down, the task at the head of the work queue is dropped, and then execution is retried (which can fail again, causing this to be repeated.)

CountDownLatch

CountDownLatch : This framework allows a java thread to wait until other set of threads completes their tasks.

Use cases:

  1. Achieving Maximum Parallelism: Sometimes we want to start a number of threads at the same time to achieve maximum parallelism

  2. Wait for N threads to complete before start of executing other code block

  3. Deadlock detection.

More details are listed in this article

ForkJoinPool

The ForkJoinPool is similar to the Java ExecutorService but with one difference. The ForkJoinPool makes it easy for tasks to split their work up into smaller tasks which are then submitted to the ForkJoinPool too. Task stealing happens in ForkJoinPool when free worker threads steal tasks from busy worker thread queue.

public ForkJoinPool(int parallelism,
            ForkJoinPool.ForkJoinWorkerThreadFactory factory,
            Thread.UncaughtExceptionHandler handler,
            boolean asyncMode)
Creates a ForkJoinPool with the given parameters.

Parameters:

parallelism - the parallelism level. For default value, use Runtime.availableProcessors().

factory - the factory for creating new threads. For default value, use defaultForkJoinWorkerThreadFactory.

handler - the handler for internal worker threads that terminate due to unrecoverable errors

asyncMode - if true, establishes local first-in-first-out scheduling mode for forked tasks that are never joined.

Regarding main query:

You can use ExecutorService.invokeAll() or CountDownLatch framework or ForkJoinPool . All these frameworks are complimentary to each other varying of granularity to control the execution of tasks from high level to low level.

EDIT:

Have a look at related SE questions:

What are the advantages of using an ExecutorService?

Java's Fork/Join vs ExecutorService - when to use which?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...