When would you want to use two cached thread pools? - java

Consider this example from a Netty tutorial (although it's not the only example of it I've seen):
Executor bossPool = Executors.newCachedThreadPool();
Executor workerPool = Executors.newCachedThreadPool();
ChannelFactory channelFactory = new NioClientSocketChannelFactory(bossPool, workerPool);
Two separate cached thread pools are created here. But why? I can understand the purpose of multiple threads pools if they are of fixed size, but cached thread pools are not. So why would you want to have multiple cached thread pools if you can just have one that constantly expands? In fact, wouldn't it be better to have just one? Because if you have two different threads submitting tasks, then it means it is more likely that the idle worker threads are utilized.
I'm wondering about this because I'm writing the networking for a server, and I am handling UDP and TCP connections separately. I want to dispatch handling tasks to a thread pool and I am considering using cached thread pools for that. However, I don't know if I should use one or two.
Thanks.

The only reason I can think of to have 2 cached thread pools is if you need to do operations on the pools differently. For example, you might have two classes of tasks and you want to do awaitTermination() on one of the thread-pools that handles one class of tasks but not the other. Or maybe you want to shutdownNow() one of the pools without affecting the other pool that you will allow to drain. Or maybe you have a different thread factory for each of the pools -- although not evident in your code example.

You can use different NamedThreadFactory for monitoring purpose.
Also idle threads in cached thread pool are killed after 60 seconds, hence they could have different lifecycles. Internally it use its own BlockingQueue ReentrantLock and other synchronization for managing threads in pool. Creating new thread pool could possible decrease contention. Also thread pools could have different lifecycles.

One pool most probably is for taking the initial request and the other is for processing it

Related

How is a thread pool able to re-use threads?

Our current course assignment specifies that we are supposed to create a manager for a thread pool using the "Object Pool Manager" design pattern which spawns a set amount of threads. The ownership of these threads shall be transferred to the client and then back to the pool after the client has finished using it. If no thread exists in the pool then the client has to wait.
My confusion comes from the fact that a thread is supposedly not reusable, which defeats the purpose of pooling them. Have I understood the assignment incorrectly?
Threads are reusable as long as they have not ended. A pool of threads generally involves threads that do work as it is given to them, and then wait for more work. Thus, they never end until explicitly told to do so. The trick is designing them in a way such that the work they are given ends, but the thread itself does not. Thread pools are useful because it is often relatively expensive to create/destroy threads.
#Kaliatech has already explained the concept behind re-use of threads. Also "The ownership of these threads shall be transferred to the client" is slightly misleading as the ownership of threads generally remain with the thread-pool/object-pool as it is the manager of this pool and the client should simply submits the task to the pool which can either complete successfully or fail. The thread continues to run ready to pick the next task submitted to the pool. As a design too the separation of task object ( Runnable/Callable) and the object representing thread execution (Thread) are designed to be different. Should the need arise the thread-pool is responsible for ramping up/down the number of threads as they are expensive to create and manage. Java ThreadPoolExecutor will be a good example to refer to how typically such a thread pool works.

New threads vs. reusing threads

We have a desktop application that has some background threads and, because of execution of external commands, also needs threads for handling the out and err streams.
We could either create new threads and let them finish or we could reuse threads. Would reusing threads have some benefit, e.g. in case of performance or memory usage?
There is no way to reuse a Thread because Thread once finishes (exit the run() method) its Thread.State passes from Thread.State.RUNNABLE to Thread.State.TERMINATED and the Thread class does not have a setState(Thread.State) method for setting its state to reuse it.
However we can take help of Thread Pooling in Java. In case of thread pool, a group of fixed size threads are created. A thread from the thread pool is pulled out and assigned a job by the service provider. After completion of the job, thread is contained in the thread pool again.
Advantage of Thread Pooling :
Thread pooling saves the virtual machine the work of creating brand new threads for every short-lived task.
It minimizes overhead associated with getting a thread started and cleaning it up after it dies
By creating a pool of threads, a single thread from the pool can be recycled over and over for different tasks.
Reduce response time because a thread is already constructed and started and is simply waiting for its next task
JDK 1.5 and above, you should try not to create Thread as much as possible.
Refer : http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html. Try to use Thread pool executor.
Reusing a thread has the following advantage:
no new object needs to be created (thread object)
lower latency because the task can be picked up by an existing idle thread
no old object needs to be garbage collected
using a pool also introduces a limit to concurrently running threads (averages out load spikes)

increase Thread start performance in java

Is there a way to increase the performance of Thread.start method. as i know Thread.start will call the run method of the tread in a separate thread but i have found that it need time more than simple method call in the calling context.
Starting threads definitely involves overhead. You may want to consider thread pooling.
http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
Thread.start is native. It does a lot more than calling run - it uses Operating System calls to create a thread stack and lots of other things. Consider using a Thread Pool.
Starting threads, context switching and destroying threads all require precious CPU cycles. So it is best to use Thread Pooling which suits your requirement.
There are various options available:
Cached Thread Pool - caches some threads to improve performance
Single Thread pool executor - A single thread executor
Fixed Thread Pool executor - An executor with fixed size
Switching can be reduced by creating n threads based on your hardware configuration and other parameters.
Advantage of executors over Thread.start():
Re use of existing threads, so threads are not created every time a task is submitted
Thread management is done by executors
Thread creation always takes time. The traditional approach
new Thread(runnableObj).start();
creates new Thread everytime we call start() method.
Use Executors, if you don't want to spend extra time in creating threads while your business logic is being run. You can configure and create Thread Pools when your application starts.
Here is a good short tutorial for Executors

Should any threads reside outside of the thread pool?

When using a thread pool, is it beneficial to still use singular thread objects for a specific task. I'm wondering in terms of a server in Java, whether or not the thread which is listening for connections, should share its resources with any other threads which are then allocated from this one listening thread? I may also be missing the point as I'm not familiar with this concept.
Yes, singular tasks that have to run concurrently can have their own threads outside of the thread pool. Forcing every thread to be part of the pool might obscure your design because you need all kinds of machinery to make concurrent tasks look like worker threads.
I'd create two pools, one for listening and one for internal tasks. This way you're never putting your server at risk of not being able to listen for connections.
The pool for internal tasks can be small if it's only a thread now and then, but at least it's safely isolated.
Resource sharing might be necessary in cases where your server needs to maintain a global application state (e.g. using an AtomicLong for the number of requests served by your server etc.). Your main thread would typically wait, ready to accept incoming connections/requests. You then update the global state (like hit counter), create a new "job" based on the new request (typically a Runnable or Callable) and submit it to a thread pool (java.util.concurrent) provides them.
The purpose of a thread pool is just to help you manage your threads. In other words, a thread pool handles the creation and termination of threads for you as well as giving work to idle threads. Threads that are blocked or waiting will not receive new tasks.
Your connection listener will probably be in an infinite loop waiting for connections and thus never be idle (although it could be in a wait state). Since this is the case, the connection listener thread will never be able to receive new tasks so it wouldn't make sense to pool it with the other threads.
Connection listening and connection handling are also two different things. From that perspective the connection listener shouldn't be pooled with the connection handlers either.
SImilar to #larsman's comment, I would do what ever you feel is simpler and clearer. I have tended to use one thread pool for everything because it appeared to be easier to manage. You don't have to do it that way and the listening task can be its own thread.

Is it OK to create multiple threadpools (ExecutorService)?

I created multiple ExecutorService instances in my code, usually each UI page has one ExecutorService instance. Each ExecutorService instance will execute some http get request threads.
private ExecutorService m_threadPool = Executors.newCachedThreadPool();
Is it OK to do that?
The problem I met is that sometimes the http get requests got response code -1 from HttpURLConnection getResponseCode() call. I don't know whether it is caused by multiple threadpool instances.
Thanks.
ExecutorService per se is just another object so there's no big overhead. But each thread pool comes with a number of idle threads by default and those are a cause of a major resource waste. I would suggest setting the default number of pre-generated threads in each pool small (1 or 0 if you are not sure whether any requests are sent) in order to reduce the cost of creating extra objects. Threads would be created on demand and you'll be able to keep your code clean.
Another solution is to use a single thread pool but to maintain a separate list of tasks for each UI window. In this case when window gets closed you'll have to iterate over all tasks and cancell the running ones manually (this can also be done in a separate thread). A task may be represented by a Future<?> (it has handy isDone() and cancel() methods).
It shouldn't be caused by your thread pool instances. However, I'd say that having more than one thread pool is questionable. Why would you need it? It could lead to a lot of unnecessary threads, and thereby unnecessary memory use.

Categories