When to create multiple executor service per application java - java

When is it a good idea to create more than one executor service per run of a program/application? Why would you do it, instead of just starting up executors.newcachedthreadpool() at the beginning and submitting all callables to it.

You might need different flavours (say a fixed thread pool or a scheduled executor)
Encapsulation: if a specific class needs to run things through an executor, it makes sense that this class be responsible to decide its execution policy, which is an implementation detail
Specialisation - corollary of the previous point:
some tasks need many threads (typically network tasks)
while others only need a few (CPU-bound task)
and some should only use one (if you read/write on your local hard drive for example)
There certainly are situations where you want to pass an executor to an object because you want the calling code to control how some tasks will be executed
Bottom line, I can't think of a reason why, for a sufficiently large project, you would want to just use one thread pool for your whole program.

A typical use case for adding an executor service, is when you want your service to use a different thread pooling strategy, or have two different pool sizes. Your application may contain a class of runnables that you would like to submit to a large, fixed size pool, and another kind of runnables where you would want a smaller pool.
Keep in mind that ExecutorService has several implementations:
ThreadPoolExecutor
ScheduledThreadPoolExecutor
Have a look at the constructor parameters for ThreadPoolExecutor, these are all things you may want to tune, based on the kind of tasks you are submitting:
ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue)
Notice that you can also pass in a Queue, so you can control the queuing strategy that your thread pool uses.

Related

Advantages of Executors over new Thread

What benefit is there to use Executors over just Threads in a Java program.
Such as
ExecutorService pool = Executors.newFixedThreadPool(2);
void someMethod() {
//Thread
new Thread(new SomeRunnable()).start();
//vs
//Executor
pool.execute(new SomeRunnable());
}
Does an executor just limit the number of threads it allows to have running at once (Thread Pooling)? Does it actually multiplex runnables onto the threads it creates instead? If not is it just a way to avoid having to write new Thread(runnable).start() every time?
Yes, executors will generally multiplex runnables onto the threads they create; they'll constrain and manage the number of threads running at once; they'll make it much easier to customize concurrency levels. Generally, executors should be preferred over just creating bare threads.
Creating new threads is expensive. Because Executors uses a thread pool, you get to easily reuse threads, resulting in better performance.
Does an executor just limit the number of threads it allows to have running at once (Thread Pooling)?
Executors#newFixedThreadPool(int), Executors#newSingleThreadExecutor do this, each one under different terms (read the proper javadoc to know more about it).
Does it actually multiplex runnables onto the threads it creates instead?
Yes
If not is it just a way to avoid having to write new Thread(runnable).start() every time?
ExecutorService helps you to control the way you handle threads. Of course, you can do this manually, but there's no need to reinvent the wheel. Also, there are other functionalities that ExecutorService provides you like executing asynchronous tasks through the usage of Future instances.
There are multiple concerns related to thread.
managing threads
resource utilization
creation of thread
Executors provides different kind of implementation for creating a pool of threads. Also thread creation is a costly affair. Executors creates and manages these threads internally. Details about it can be found in the below link.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ThreadPoolExecutor.html
As I said over in a related question, Threads are pretty bad. Executors (and the related concurrency classes) are pretty good:
Caveat: Around here, I strongly discourage the use of raw Threads. I
much prefer the use of Callables and FutureTasks (From the javadoc: "A
cancellable asynchronous computation"). The integration of timeouts,
proper cancelling and the thread pooling of the modern concurrency
support are all much more useful to me than piles of raw Threads.
For example, I'm currently replacing a legacy piece of code that used a disjoint Thread running in a loop with a self-timer to determine how long it should Thread.sleep() after each iteration. My replacement will use a very simple Runnable (to hold a single iteration), a ScheduledExecutorService to run one of the iterations and the Future resulting from the scheduleAtAFixedRate method to tune the timing between iterations.
While you could argue that replacement will be effectively equivalent to the legacy code, I'll have replaced an arcane snarl of Thread management and wishful thinking with a compartmentalized set of functionality that separates the concerns of the GUI (are we currently running?) from data processing (playback at 5x speed) and file management (cancel this run and choose another file).

How to limit a task from using all threads in a thread pool?

I'm using a thread pool to execute tasks in the background of my application. However, some of my tasks are heavier than others. So I'd like to limit the heavy tasks to a certain subset of the thread pool, thereby leaving at least a few threads open for any lightweight tasks to execute.
Is there a simple way to do this?
The most simple way is to use separate thread pools for different "tasks weight".
Even you can create separate class which exposes separate methods for differents tasks.
As it was said, the cleanest way is to use a separate thread pool for heavy threads.
Another way is to use a Semaphore. Create a semaphore with a count of, for example, three. Heavy threads have to acquire() it first. Only three heavy ones would be able to do so. The rest will wait (or fail, if you use tryAcquire()).
Of course, the thread needs to "know" it is a "heavy" one. For third-party threads it doesn't work, so see "two pools" approach again. :-)

ThreadPoolExecutor on java doc

at http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html
you can read the description of parameters to constructor.
Specifically in the "Core and maximum pool sizes" paragraph, it's written:
If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.
...
By setting maximumPoolSize to an essentially unbounded value such as Integer.MAX_VALUE, you allow the pool to accommodate an arbitrary number of concurrent tasks.
Now I can't understand what "only if the queue is full" in the first part stands for...
Will ThreadPoolExecutor wait until queue is full or it will simply create a new worker?
An suppose now that we have more tasks that aren't asynchronous between them: using a ThreadPoolExecutor could cause a deadlock? Supposing that my first 10 tasks are producer and that CorePoolSize is 10, then succeeding consumer tasks will go to queue and won't run until the queue is full? If so this behavior may cause deadlock because first 10 producers could go on wait, suspending all 10 threads of the Core.
When the queue is full?
I'm not sure I understood well the documentation, because Executors.newCachedThreadPool() seems to create a new Worker until maxPoolSize is reached and THEN it sends task to queue.
I'm a little confused.
Thank you
When you construct the ThreadPoolExecutor, you pass in an instance of BlockingQueue<Runnable> called workQueue, to hold the tasks, and it is this queue that is being referred to.
In fact, the section of the docs called "Queuing" goes into more detail about the phrase you're confused about:
Any BlockingQueue may be used to transfer and hold submitted tasks. The use of this queue interacts with pool sizing:
If fewer than corePoolSize threads are running, the Executor always prefers adding a new thread rather than queuing.
If corePoolSize or more threads are running, the Executor always prefers queuing a request rather than adding a new thread.
If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
As for your second part, about inter-task dependencies - in this case I don't think it's a good idea to put them into an ExecutorService at all. The ExecutorService is good for running a self-contained bit of code at some point in the future, but by design it's not meant to be strongly deterministic about when this happens, other than "at some convenient point in the (hopefully near) future, after tasks that were previously queued have started."
Combine this lack of precision of timing, with the hard ordering requirements that concurrent operation imposes, and you can see that having a producer and a consumer that need to talk to each other, put into a general purpose ExecutorService, is a recipe for very annoying and confusing bugs.
Yes, I'm sure you could get it to work with sufficient tweaking of parameters. However, it wouldn't be clear why it worked, it wouldn't be clear what the dependencies were, and when (not if) it broke, it would be very hard to diagnose. (Harder than normal concurrency problems, I suspect). The bottom line is that an ExecutorService isn't designed to run Runnables with hard timing restrictions, so this could even be broken by a new release of Java, because it doesn't have to work like this.
I think you're asking the wrong question, by looking at the details when perhaps your concepts are a little shaky. Perhaps if you explained what you wanted to achieve there would be a better way to go about it.
To clarify your first quote - if the executor already has corePoolSize threads running, and all of those threads are busy when a new task is submitted, it will not create any more threads, but will enqueue the task until one of the threads becomes free. It will only create a new thread (up to the maxPoolSize limit) when the queue becomes full. If the queue is huge (i.e. bounded only by memory constraints) then no more than corePoolSize threads will ever be created.
Executors.newCachedThreadPool() will create an executor with a zero-sized queue, so the queue is always full. This means that it will create a new thread (or re-use an idle one) as soon as you submit the task. As such, it's not a good demonstration of what the core/max/queue parameters are for.

Why is there no scheduled cached thread pool provided by the Java Executors class?

Executors provides newCachedThreadPool() and newScheduledThreadPool(), but not newCachedScheduledThreadPool(), what gives here? I have an application that receives bursty messages and needs to schedule a fairly lengthy processing step after a fixed delay for each. The time constraints aren't super tight, but I would prefer to have more threads created on the fly if I exceed the pool size and then have them trimmed back during periods of inactivity. Is there something I've missed in the concurrent library, or do I need to write my own?
By design the ScheduledThreadPoolExecutor is a fixed size. You can use a single threaded version that submits to a normal ExecutorService for performing the task. This event thread + worker pool is fairly ease to coordinate and the flexibility makes up for the dedicated thread. I've used this in the past to replace TimerTasks and other non-critical tasks to utilize a common executor as a system-wide pool.
Suggested here Why does ScheduledThreadPoolExecutor only accept a fixed number of threads? workaround:
scheduledExecutor = new ScheduledThreadPoolExecutor(128); //no more than 128 threads
scheduledExecutor.setKeepAliveTime(10, TimeUnit.SECONDS);
scheduledExecutor.allowCoreThreadTimeOut(true);
java.util.concurrent.Executors is nothing more than a collection of static convenience methods that construct common arrangements of executors.
If you want something specific that isn't offered by Executors, then feel free to construct your own instance of the implemention classes, using the examples in Executors as a guide.
Like skaffman says, Executors is only a collection of factory method. if you need a particular instance, you can always check all existing Executor implementors. In your case, i think that calling one of the various constructors of ScheduledThreadPoolExecutor would be a good idea.

When should we use Java's Thread over Executor?

Executor seems like a clean abstraction. When would you want to use Thread directly rather than rely on the more robust executor?
To give some history, Executors were only added as part of the java standard in Java 1.5. So in some ways Executors can be seen as a new better abstraction for dealing with Runnable tasks.
A bit of an over-simplification coming... - Executors are threads done right so use them in preference.
I use Thread when I need some pull based message processing. E.g. a Queue is take()-en in a loop in a separate thread. For example, you wrap a queue in an expensive context - lets say a JDBC connection, JMS connection, files to process from single disk, etc.
Before I get cursed, do you have some scenario?
Edit:
As stated by others, the Executor (ExecutorService) interface has more potential, as you can use the Executors to select a behavior: scheduled, prioritized, cached etc. in Java 5+ or a j.u.c backport for Java 1.4.
The executor framework has protection against crashed runnables and automatically re-create worker threads. One drawback in my opinion, that you have to explicitly shutdown() and awaitTermination() them before you exit your application - which is not so easy in GUI apps.
If you use bounded queues you need to specify a RejectedExecutionHandler or the new runnables get thrown away.
You might have a look at Brian Goetz et al: Java Concurrency in Practice (2006)
There is no advantage to using raw threads. You can always supply Executors with a Thread factory, so even the option of custom thread creation is covered.
You don't use Thread unless you need more specific behaviour that is not found in Thread itself. You then extend Thread and add your specifically wanted behaviour.
Else just use Runnable or Executor.
Well, I thought that a ThreadPoolExecutor provided better performance for it manages a pool of threads, minimizing the overhead of instantiating a new thread, allocating memory...
And if you are going to launch thousands of threads, it gives you some queuing functionality you would have to program by yourself...
Threads & Executors are different tools, used on different scenarios... As I see it, is like asking why should I use ArrayList when I can use HashMap? They are different...
java.util.concurrent package provides executor interface and can be used to created thread.
The Executor interface provides a single method, execute, designed to be a drop-in replacement for a common thread-creation idiom. If r is a Runnable object, and e is an Executor object you can replace
(new Thread(r)).start();
with
e.execute(r);
Refer here
It's always better to prefer Executor to Thread even for single thread as below
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
You can use Thread over Executor in below scenarios
Your application needs limited thread(s) and business logic is simple
If simple multi-threading model caters your requirement without Thread Pool
You are confident of managing thread(s) life cycle + exception handling scenarios with help of low level APIs in below areas : Inter thread communication, Exception handling, reincarnation of threads due to unexpected errors
and one last point
If your application does not need customization of various features of ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
In all other cases, you can go for ThreadPoolExecutor

Categories