How to create and process messages from worker threads - java

How to create asynchronous messages from worker threads to the managing thread. The framework is below. In the snippet, Worker implements Runnable, and threadManager is ExecutorService. The Worker threads are long running, and should pass periodic progress messages up to the manager. One option is to use a blocking queue, but I haven't done that before.
RunnableTester_rev2.threadManager = Executors.newFixedThreadPool( nThreadsAllowed );
final List<Worker> my_tasks = new ArrayList<Worker>();
for ( int i = 0; i < nThreadsToRun; i++ )
{
// The Worker thread is created here.
// Could pass a blocking queue to handle messages.
my_tasks.add( new Worker( ) );
}
final List<Future<?>> fList = new ArrayList<Future<?>>();
for ( final Worker task : my_tasks )
{
fList.add( RunnableTester_rev2.threadManager.submit( task ) );
}
RunnableTester_rev2.threadManager.shutdown();
/**
* Are we all done
*/
boolean isDone = false;
/**
* Number of threads finished
*/
int nThreadsFinished = 0;
/**
* Keep processing until all done
*/
while ( !isDone )
{
/*
* Are all threads completed?
*/
isDone = true;
int ii = 0;
nThreadsFinished = 0;
for ( final Future<?> k : fList )
{
if ( !isThreadDoneList.get( ii ) )
{
final boolean isThreadDone = k.isDone();
if ( !isThreadDone )
{
// Reduce printout by removing the following line
// System.out.printf( "%s is not done\n", mywks.get( ii ).getName() );
isDone = false;
}
}
else
{
nThreadsFinished++;
}
ii++;
}
/*
* WOULD LIKE TO PROCESS Worker THREAD MESSAGES HERE
*/
}

That's really complicated. I would have done something like this.
// no need to use a field.
ExecutorService threadManager = Executors.newFixedThreadPool( nThreadsAllowed );
List<Future<Result>> futures = new ArrayList<Future<Result>>();
for ( int i = 0; i < nThreadsToRun; i++ )
// Worker implements Callable<Result>
futures.add(threadManager.submit(new Worker( )));
threadManager.shutdown();
threadManager.awaitTermination(1, TimeUnit.MINUTE);
for(Future<Result> future: futures) {
Result result = future.get();
// do something with the result
}

I'd use a BlockingQueue. You could try something like this:
final BlockingQueue<Message> q = new LinkedBlockingQueue<Message>();
// start all the worker threads,
// making them report progress by adding Messages into the queue
for (...) {
threadManager.submit(new Runnable() {
// initialize the worker
q.offer(new Message("10% completed"));
// do half of the work
q.offer(new Message("50% completed"));
// do the rest of the work
q.offer(new Message("100% completed"));
});
}
// after starting all the workers, call a blocking retrieval method
// on the queue, waiting for the messages
while (!(everything is done)) {
Message m = q.take();
// process the message
}
The idea is that all the worker threads and the main thread share a common blocking queue. The worker threads are the producers, and the main thread is the consumer.
Here I use .offer(...), but you could use .add(...) and you'd get the same in this case. The difference would be that the former would return false if the queue is full, while the latter would throw an exception. It can't happen here, since I've instantiated an unbounded queue (you could obviously get an OutOfMemoryError). If you use .put(...), however, you'd have to deal with an unchecked InterruptedException (which is not useful in this case: it can't get thrown because the queue is never full -- it is unbounded --, so the method will never block).
Obviously, you can improve it by refactoring the calls to q.offer(...) into a reportStatus(...) method, or something like that.
Maybe you want something different than what I proposed above. Maybe you want the main thread to get asynchronous messages only when each worker thread finishes its work.
My solution is similar that the one proposed by Peter Lawrey, the difference being that, with this solution, the managing thread will get notified as soon as any of worker thread finishes (while with Peter's solution, the result from the worker threads will be retrieved in order -- so, if the first worker thread takes forever to run, even if all the other worker threads finish their jobs you won't know it). Depending on what you are doing, you could get increased performance.
Note that with this solution you cannot infer which thread finished its work (to do so, your Worker class would have to have a method like .getJobId() or something like that), while with Peter's solution you will know exactly which thread finished its work (because you are iterating in the futures list in the same order you instantiated and started the Workers).
If this is the case, you can use an ExecutorCompletionService. It encapsulates an ExecutorService and provides a .take() method (blocking retrieval) that will return Futures from the executor service right after they've completed:
ExecutorCompletionService<Worker> ecs = new ExecutorCompletionService(executorService);
// Worker has to be a callable
// Now you submit your tasks to the ecs:
for (...) {
ecs.submit(new Worker(...));
}
// Now you block on .take():
while (!(everything is done)) {
Future<Worker> f = ecs.take();
// f.get(), for example, to check the results
}
The CompletionService guarantees that, once you take a Future, a call to its .get() method will complete immediately: either by returning the result, or by throwing an ExecutionException, encapsulating the exception thrown by the Callable.

Related

Task schedule itself inside run() method will cause too many thread created?

According to this post:
public class ConditionCheckingTask implements Runnable
{
private final ScheduledExecutorService ses ;
private final Instant whenInstantiated = Instant.now() ;
// Constructor
public ConditionCheckingTask( final ScheduledExecutorService ses ) {
this.ses = ses ;
}
#Override
public void run() {
if( someConditionIsTrue ) {
doSomething ;
} else if ( ChronoUnit.MINUTES.between( this.whenInstantiated , Instant.now() ) > 100000 ) {
// We have exceeded our time limit, so let this task die.
return ;
} else { // Else wait a minute to check condition again.
this.ses.schedule( this , 1 , TimeUnit.MINUTES ) ;
}
}
}
The task schedule itself inside run() method. Suppose the time limit is 100000, then 100000 threads will be created? Since each schedule call will need a separate thread to run, right?
each schedule call will need a separate thread to run, right?
Probably not.
All we know from the code that you showed is that ses refers to a ScheduledExecutorService, and since that's only an interface, we don't actually know what it will do; but any practical implementation of that interface most likely will be some kind of thread pool.
A simple thread pool has a blocking queue of tasks, and a small number of worker threads that each sit in a loop awaiting tasks and performing them;
while (true) {
Runnable task = queue.take();
task.run();
}
In this way, the number of threads used can be much smaller than the number of tasks that are submitted to the queue.
A ScheduledExecutorService such as ScheduledThreadPoolExecutor works in pretty much the same way, except that the queue is some kind of priority queue. A priority queue returns the tasks in the order in which they are scheduled to run instead of returning them in the same order as they were submitted. Each worker loops, waiting until a task at the head of the queue is due, and then it take()s the task, runs it, and goes back to await the next task, same as in the simple thread pool.

Java Thread Pool Timing Issue

I'm trying to use a thread pool to execute some code, however I'm having some trouble getting it to run without errors.
Here is my current structure:
while (!(queue.IsEmpty()))
{
currentItem= queue.GetNextItem();
for (int i = 0; i < currentItem.destinations.GetNoOfItems(); i++) //for each neighbor of currentItem
{
threadPool.submit(new NeighbourThread(currentItem, allVertices, routetype, pqOpen, i, endLocation));
}
//threadPool.shutdown();
}
NeighbourThread class:
public class NeighbourThread implements Runnable {
Vertex tempVertex, endLocation;
VertexHashMap allVertices;
int routetype, i;
PriorityQueue pqOpen;
public NeighbourThread(Vertex tempVertex, VertexHashMap allVertices, int routetype, PriorityQueue pqOpen, int i, Vertex endLocation)
{
...variables
}
#Override
public void run() {
...execution code
}
}
My idea is that it will create the amount of threads required based on currentItem.destinations.GetNoOfItems()(as it reuses threads, I'm assuming if it reaches the limit on thread creation it will wait for a thread to finish execution and reuse it).
Once the threads have been allocated, it will submit each runnable to the thread and start it.
However I need my program to wait for all threads to finish execution before it loops back to the while loop.
After reading the documentation on .shutdown(), I think that stops any future use of the threadpool, which I'm guessing is why I get this error:
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.FutureTask#3d4eac69 rejected from java.util.concurrent.ThreadPoolExecutor#42a57993[Shutting down, pool size = 3, active threads = 1, queued tasks = 0, completed tasks = 3]
I'm trying to improve execution time on my program and as I'm currently doing over 1.5 million invocations of what will be in the run() method, I feel this will help.
So is there anyway to get the program to wait until the threads have finished before continuing with the while loop?
The easiest solution is to use the Futures to notify you when they have completed. Unfortunately, Java does not support listenable Futures out of the box, but you can use the Guava library to supplement you here.
Guava adds the ListeneableFuture, which you can make using the Futures utility class:
ListeningExecutorService executor = MoreExecutors.listeningDecorator(threadPool);
// Collect the futures as you add them to the threadpool
List<ListenableFuture<?>> futures = new ArrayList<>();
while (! queue.IsEmpty())
{
currentItem = queue.GetNextItem();
for (int i = 0; i < currentItem.destinations.GetNoOfItems(); i++)
{
// NeighbourThread should be a Runnable and not a Thread!
futures.add(executor.submit(new NeighbourThread(currentItem, allVertices, routetype, pqOpen, i, endLocation)));
}
}
// Get notified when they're all done (doesn't imply success!)
Futures.allAsList(futures)).addListener(new Runnable() {
// When this callback is executed, then everything has finished
}, MoreExecutors.directExecutor());
Alternatively, you could do this with a CountdownLatch if you know how many items you need to run upfront.

How does newCachedThreadPool reuse threads?

I want to ask for a little more detail to the same question posted by Zeller over a year ago...
The javadoc says that the service returned by Executors.newCachedThreadPool reuses threads. How is this possible?
I get how the queue structure is setup internally, what I don't see is how it reuses threads in the queue.
All examples I've seen have the developer create an instance of their thread and pass it in through the "execute" method.
For example...
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread(i); //will create 10 instances
executor.execute(worker);
}
I understand that a thread pool can easily manage the life cycle of each thread, but again, I see no methods nor the ability to access or restart any of the threads in the pool.
In the above example, I would then expect that each thread would be started, run, terminated and disposed of by the thread pool, but never reused.
A messaging system would be an example of where you'd need this. Say you have an onMessage handler and you'd like to reuse one of the threads in the pool to handle it, so I'd expect methods like...
worker = executor.getIdleThread;
worker.setData(message);
executor.resubmit(worker);
or maybe have the ExecutorService acting as a factory class and have it return an instance of your threads, where internally it decides to create a new one or reuse an old one.
ExecutorService executor = Executors.newCachedThreadPool(WorkerThread);
Runnable worker = executor.getThread;
worker.setData(message);
So I'm missing something. It's probably something simple but I've spent the afternoon reading tutorials and examples and still haven't figured it out. Can someone shed some light on the subject?
I was curious too how this was possible since Threads can't be restarted, so I analyzed the code of ThreadPoolExecutor which is the implementation of all the ThreadPool ExecutorService you get through the static constructor.
First of all as stated in the other answer you don't use Threads, but Runnables in ThreadPools, because that would defeat the purpose. So here is a detailed explaination how an ExecutorService reuses Threads:
You usually add a Runnable through submit() which internally calls the execute() method. Basically this adds the runnable to a queue and adds a Worker if none is working ATM
public void execute(Runnable command) {
...
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reje
ct(command);
}
The executor maintains a bunch of Worker (inner Class of ThreadPoolExecutor). It has your submitted runnable and a Thread that will be created through the ThreadFactory you maybe set or else just a default one; also the Worker itself is a Runnable, which is used to create the Thread from the factory
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
...
Worker(Runnable firstTask) {
this.firstTask = firstTask;
this.thread = getThreadFactory().newThread(this);
}
public void run() {
runWorker(this);
}
...
}
When adding a Worker it gets kickstarted
private boolean addWorker(Runnable firstTask, boolean core) {
...
Worker w = new Worker(firstTask);
Thread t = w.thread;
...
t.start();
...
return true;
}
the runWorker() method runs in a loop and get with getTask() the runnables you submitted which are queued in the workingQueue and will wait at getTask unitl a timeout happens.
final void runWorker(Worker w) {
Runnable task = w.firstTask;
w.firstTask = null;
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
clearInterruptsForTaskRun();
try {
beforeExecute(w.thread, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
...
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
processWorkerExit(w, completedAbruptly);
}
}
Here is the getTask() method
private Runnable getTask() {
...
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
..
} catch (InterruptedException retry) {
...
}
}
}
tl;dr So basically the Threadpool maintains worker threads that run in loops and execute runnables given by a blocking queue. The worker will be created and destroyed due to demand (no more tasks, a worker will end; if no free worker and < maxPoolSize then create new worker). Also I wouldn't call it "reuse" more the thread will be used as a looper to execute all runnables.
I understand that a thread pool can easily manage the life cycle of
each thread, but again, I see no methods nor the ability to access or
restart any of the threads in the pool.
The management of threads is done internally. The ExecutorService interface only provides the externally visible methods.
The javadoc of newCachedThreadPool simply states
Creates a thread pool that creates new threads as needed, but will
reuse previously constructed threads when they are available. [...] Calls to execute will reuse
previously constructed threads if available. If no existing thread is
available, a new thread will be created and added to the pool. Threads
that have not been used for sixty seconds are terminated and removed
from the cache. Thus, a pool that remains idle for long enough will
not consume any resources. [...]
So that is the guarantee you get. If you want to know how it is implemented, you can look at the source code, in particular, the code of ThreadPoolExecutor. Basically, idle threads will terminate after not executing a task after some time.

Terminating all child threads on closing the stage/window

I have multiple instances of child threads which are started and should continue to execute in till the applications exits.
I have classes which extends Task and I create the threads as
new Thread(object of the class).start();
All the threads should be terminated on closing of the primary stage.
primaryStage.onCloseOperation(){...}
I'd manage your threads explicitly from the beginning. In particular, have a thread pool in your parent class like so:
ExecutionService exec = Executors.newCachedExecutionService();
then, if your tasks are meant to keep running (instead of being periodically scheduled) code your tasks responsive to interruption like so:
while(!Thread.currentThread().isInterrupted()){
do stuff;
}
This will make the task run until interrupted. It is important in this case that you never ignore an InterruptedException, because InterruptedException set isInterrupted to false when they are thrown. Do this when you see an InterruptedException:
}catch(InterruptedException e){
Thread.currentThread().interrupt();
return;
}
Then, you can start your child tasks like so:
for(task : tasks){
exec.execute(task);
}
Now, when your parent task finishes, you can simply call:
exec.shutdownNow();
To stop your child tasks. If your child tasks use Thread.currentThread().isInterrupted(), you must use shutdownNow() (shutdown() only works if you want to wait for tasks to stop by themselves).
You should think of using ThreadGroup to group all the threads and then controlling their behavior. Java 5 added the ThreadInfo and ThreadMXBean classes in java.lang.management to get state information.
Here is a sample example to achieve this using tutorial available herehttp://nadeausoftware.com/articles/2008/04/java_tip_how_list_and_find_threads_and_thread_groups:
Getting a list of all threads
Another enumerate( ) method on a ThreadGroup lists that group's threads. With a true second argument, it will recursively traverse the group to fill a given array with Thread objects. Start at the root ThreadGroup and you'll get a list of all threads in the JVM.
The problem here is the same as that for listing thread groups. If the array you pass to enumerate( ) is too small, some threads might be silently dropped from the returned array. So, you'll need to take a guess at the array size, call enumerate( ), check the returned value, and try again if the array filled up. To get a good starting guess, look to the java.lang.management package. The ManagementFactory class there returns a ThreadMXBean who's getThreadCount( ) method returns the total number of threads in the JVM. Of course, this can change a moment later, but it's a good first guess.
Thread[] getAllThreads( ) {
final ThreadGroup root = getRootThreadGroup( );
final ThreadMXBean thbean = ManagementFactory.getThreadMXBean( );
int nAlloc = thbean.getThreadCount( );
int n = 0;
Thread[] threads;
do {
nAlloc *= 2;
threads = new Thread[ nAlloc ];
n = root.enumerate( threads, true );
} while ( n == nAlloc );
return java.util.Arrays.copyOf( threads, n );
}
Create an ExecutorService which has a ThreadFactory to create daemon threads.
For example :
ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
#Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setDaemon(true);
return thread;
}
});
and the rest how to use it has already been said by #Enno.
Thanks Enno :)

Java - Basic Multithreading

I would like to ask basic question about Java threads. Let's consider a producer - consumer scenario. Say there is one producer, and n consumer. Consumer arrive at random time, and once they are served they go away, meaning each consumer runs on its own thread. Should I still use run forever condition for consumer ?
public class Consumer extends Thread {
public void run() {
while (true) {
}
}
}
Won't this keep thread running forever ?
I wouldn't extend Thread, instead I would implement Runnable.
If you want the thread to run forever, I would have it loop forever.
A common alternative is to use
while(!Thread.currentThread().isInterrupted()) {
or
while(!Thread.interrupted()) {
It will, so you might want to do something like
while(beingServed)
{
//check if the customer is done being served (set beingServed to false)
}
This way you'll escaped the loop when it's meant to die.
Why not use a boolean that represents the presence of the Consumer?
public class Consumer extends Thread {
private volatile boolean present;
public Consumer() {
present = true;
}
public void run() {
while (present) {
// Do Stuff
}
}
public void consumerLeft() {
present = false;
}
}
First, you can create for each consumer and after the consumer will finish it's job than the consumer will finish the run function and will die, so no need for infinite loop. however, creating thread for each consumer is not good idea since creation of thread is quite expensive in performance point of view. threads are very expensive resources. In addition, i agree with the answers above that it is better to implement runnable and not to extends thread. extend thread only when you wish to customize your thread.
I strongly suggest you will use thread pool and the consumer will be the runnable object that ran by the thread in the thread pool.
the code should look like this:
public class ConsumerMgr{
int poolSize = 2;
int maxPoolSize = 2;
long keepAliveTime = 10;
ThreadPoolExecutor threadPool = null;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
5);
public ConsumerMgr()
{
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
keepAliveTime, TimeUnit.SECONDS, queue);
}
public void runTask(Runnable task)
{
// System.out.println("Task count.."+threadPool.getTaskCount() );
// System.out.println("Queue Size before assigning the
// task.."+queue.size() );
threadPool.execute(task);
// System.out.println("Queue Size after assigning the
// task.."+queue.size() );
// System.out.println("Pool Size after assigning the
// task.."+threadPool.getActiveCount() );
// System.out.println("Task count.."+threadPool.getTaskCount() );
System.out.println("Task count.." + queue.size());
}
It is not a good idea to extend Thread (unless you are coding a new kind of thread - ie never).
The best approach is to pass a Runnable to the Thread's constructor, like this:
public class Consumer implements Runnable {
public void run() {
while (true) {
// Do something
}
}
}
new Thread(new Consumer()).start();
In general, while(true) is OK, but you have to handle being interrupted, either by normal wake or by spurious wakeup. There are many examples out there on the web.
I recommend reading Java Concurrency in Practice.
for producer-consumer pattern you better use wait() and notify(). See this tutorial. This is far more efficient than using while(true) loop.
If you want your thread to processes messages until you kill them (or they are killed in some way) inside while (true) there would be some synchronized call to your producer thread (or SynchronizedQueue, or queuing system) which would block until a message becomes available. Once a message is consumed, the loop restarts and waits again.
If you want to manually instantiate a bunch of thread which pull a message from a producer just once then die, don't use while (true).

Categories

Resources