Thread starvation deadlock example - java

In the book Effective Java by Joshua Bloch, there is this example (item 81):
// Simple framework for timing concurrent execution
public static long time(Executor executor, int concurrency,
Runnable action) throws InterruptedException {
CountDownLatch ready = new CountDownLatch(concurrency);
CountDownLatch start = new CountDownLatch(1);
CountDownLatch done = new CountDownLatch(concurrency);
for (int i = 0; i < concurrency; i++) {
executor.execute(() -> {
ready.countDown(); // Tell timer we're ready
try {
start.await(); // Wait till peers are ready
action.run();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
done.countDown(); // Tell timer we're done
}
});
}
ready.await(); // Wait for all workers to be ready
long startNanos = System.nanoTime();
start.countDown(); // And they're off!
done.await(); // Wait for all workers to finish
return System.nanoTime() - startNanos;
}
It then says:
The executor passed to the time method must
allow for the creation of at least as many threads as the given concurrency level, or
the test will never complete. This is known as a thread starvation deadlock
[Goetz06, 8.1.1].
I am not sure why this would deadlock, e.g. with 1 one thread and two tasks. Do you have an example of a way it could deadlock?

TL;DR : The concurrency variable specifies the number of tasks to be executed by the threads in the Executor thread pool passed as parameter of the method time. A deadlock occurs if those tasks are not executed by different threads.
From the CountDownLatch documentation one can read:
A CountDownLatch is initialized with a given count. The await methods
block until the current count reaches zero due to invocations of the
countDown() method, after which all waiting threads are released and
any subsequent invocations of await return immediately.
Equipped with this information, let us imagining that each task is indeed be executed by a different thread. So each thread used from the Executor to run the parallel work:
() -> {
ready.countDown(); // Tell timer we're ready
try {
start.await(); // Wait till peers are ready
action.run();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
done.countDown(); // Tell timer we're done
}
}
will call first:
ready.countDown();
and then wait in start.await(); for the master thread to call start.countDown(); (which is the only thread doing it). However, before doing so, the master thread is waiting on:
ready.await();
for the remains threads to call ready.countDown(); concurrency times. So that the master thread can resume its work. Therefore, if each of those tasks are not executed by concurrency separate threads, those threads will wait for the master thread that in turn is waiting for them as well, hence a deadlock and the statement:
The executor passed to the time method must allow for the creation of
at least as many threads as the given concurrency level, or the test
will never complete.
So regarding your question:
I am not sure why this would deadlock, e.g. with 1 one thread and two
tasks. Do you have an example of a way it could deadlock?
So let us say that concurrency=2, and you have a thread on the Executor pool and the master thread. The master thread calls:
ready.await();
which was initialized as follows:
CountDownLatch ready = new CountDownLatch(concurrency);
therefore ready.countDown(); needs to be called at least twice. However, there is only one thread on the Executor pool that calls ready.countDown(); only once and then waits at:
start.await();
for the master thread to call start.countDown();, but that thread is still waiting on ready.await();. So both threads are waiting on each other, which leads to a deadlock.

A simple invocation that would deadlock:
time(Executors.newFixedThreadPool(1), 2, () -> System.out.println("Hello world"));
Here, an executor with just 1 thread is passed in. Since concurrency is 2, the one thread waits on the "Tell timer we're ready" line for another thread to decrease the counter again.
But there is no other thread to decrease the counter, because there's only one thread. So the only thread is blocked waiting.

Related

Wake up a thread spawned using ScheduledExecutorService

I am using ScheduledExecutorService to spawn a thread as below:
private ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> scheduledFuture = ses.scheduleWithFixedDelay(() -> { cleanup(); }, 0L, 5L, TimeUnit.SECONDS);
There is a sleep of 5 seconds in between executions of the cleanup function.
In certain conditions, is there a provision to wake this thread up to start running the cleanup instead of waiting for the 5 seconds to trigger it?
Example: at time T1 -> cleanup is called, at T1+2s -> i want to wake up the thread to do the cleanup explicity
i want to wake up the thread to do the cleanup explicity.
Why not simply call cleanup() from whatever other thread sees the need?
void someTerriblyImportantFunction(...) {
...
if (thisPlaceNeedsToBeCleanedUp_Like_NOW()) {
cleanup();
}
...
}
I can do that, but i wanted the thread to always run cleanup instead.
First of all, you can not depend on the thread pool to always use the same thread when it executes your cleanup task. You created the pool by calling Executors.newScheduledThreadPool(1), but theĀ 1 argument only specifies the minimum number of threads in the pool. In a program that uses the same thread pool for more than one thing, the pool is free to create and destroy worker threads as needed, so long as it always keeps one thread ready.
Secondly, and this is just my personal opinion, it's good practice to design your multi-threaded program in such a way that, whenever some task needs to be performed, it should not matter which thread performs it. In this case, I would design cleanup() so that it can be safely called at any time, from any thread.
P.S., Also note what #Hulk said in a comment: If cleanup() takes more time than the caller is willing to wait for, then another option would be to submit a "one-shot" task to be scheduled as soon as possible by the same thread pool.
void someTerriblyImportantFunction(...) {
...
if (thisPlaceNeedsToBeCleanedUp_RealSoon()) {
ses.schedule(() -> { cleanup(); }, 1L, TimeUnit.MICROSECONDS);
}
...
}

Killing a thread invoked asynchronously using executor service

I am trying to implement timeout for a thread which is invoked asynchronously by executor.
Process flow is like below:
Thread-1: Initiates a task to run on thread-2 using below code and returns immediately without waiting for Future object result
Thread-2: Long process and wil update some store some result in cache at end
Now, the requirement is to kill Thread-2 after some timeout value without blocking Thread-1
code snippet:
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Task> future = executor.submit(new Callable<Task>() {
public Task call() throws Exception {
try{
return new Task();
}catch (Exception e) {
//print stack
}
}
});
Any insight/suggestions to implement this?
See the following answer: https://stackoverflow.com/a/2733370/1299078
But depending on what Thread-2 does, you could let the thread end regularly, i.e. define a timeout on a http-request or a DB statement or if you have a loop, define an exit condition. this way you may end up with a more proper solution and you are able to properly release resources.
You can't do it using Java's ExecutorService because it doesn't expose any method to timeout and kill/complete/finish the newly spawned thread.
However, if you must do it then you can do it by directly using Thread class, below is high level approach:
From your main thread t1, spawn your worker thread t2 which is supposed to do your long work.
In your t1, you will have hold of the t2's ORV, pass it a new thread t3 along with time after which you want t2 to finish.
In t3 (you can also do this in t1 if you wish, but since you do not wish to block t1 so you need to have another thread to do this job), once that time has elapsed call t2.interrupt(), this will basically interrupt the t2 thread.
Now in t2, you will have to periodically keep on checking whether the thread is interrupted or not (using if (Thread.interrupted()) {) and if it is interrupted then you can do whatever you want to do like - simply return therefore completing/killing/finishing the thread.
The basic ExecutorService does not provide a timeout functionality.
You could implement the timeout yourself like described by #hagrawal or you can use guava which has a very nice implementation for what you're asking for here

Difference between WAIT and BLOCKED thread states

What is the difference between thread state WAIT and thread state BLOCKED?
The Thread.State documentation:
Blocked
A thread that is blocked waiting for a monitor lock is in this state.
Waiting
A thread that is waiting indefinitely for another thread to perform a particular action is in this state
does not explain the difference to me.
A thread goes to wait state once it calls wait() on an Object. This is called Waiting State. Once a thread reaches waiting state, it will need to wait till some other thread calls notify() or notifyAll() on the object.
Once this thread is notified, it will not be runnable. It might be that other threads are also notified (using notifyAll()) or the first thread has not finished his work, so it is still blocked till it gets its chance. This is called Blocked State. A Blocked state will occur whenever a thread tries to acquire lock on object and some other thread is already holding the lock.
Once other threads have left and its this thread chance, it moves to Runnable state after that it is eligible pick up work based on JVM threading mechanism and moves to run state.
The difference is relatively simple.
In the BLOCKED state, a thread is about to enter a synchronized block, but there is another thread currently running inside a synchronized block on the same object. The first thread must then wait for the second thread to exit its block.
In the WAITING state, a thread is waiting for a signal from another thread. This happens typically by calling Object.wait(), or Thread.join(). The thread will then remain in this state until another thread calls Object.notify(), or dies.
The important difference between the blocked and wait states is the impact on the scheduler. A thread in a blocked state is contending for a lock; that thread still counts as something the scheduler needs to service, possibly getting factored into the scheduler's decisions about how much time to give running threads (so that it can give the threads blocking on the lock a chance).
Once a thread is in the wait state the stress it puts on the system is minimized, and the scheduler doesn't have to worry about it. It goes dormant until it receives a notification. Except for the fact that it keeps an OS thread occupied it is entirely out of play.
This is why using notifyAll is less than ideal, it causes a bunch of threads that were previously happily dormant putting no load on the system to get woken up, where most of them will block until they can acquire the lock, find the condition they are waiting for is not true, and go back to waiting. It would be preferable to notify only those threads that have a chance of making progress.
(Using ReentrantLock instead of intrinsic locks allows you to have multiple conditions for one lock, so that you can make sure the notified thread is one that's waiting on a particular condition, avoiding the lost-notification bug in the case of a thread getting notified for something it can't act on.)
Simplified perspective for interpreting thread dumps:
WAIT - I'm waiting to be given some work, so I'm idle right now.
BLOCKED - I'm busy trying to get work done but another thread is standing in my way, so I'm idle right now.
RUNNABLE...(Native Method) - I called out to RUN some native code (which hasn't finished yet) so as far as the JVM is concerned, you're RUNNABLE and it can't give any further information. A common example would be a native socket listener method coded in C which is actually waiting for any traffic to arrive, so I'm idle right now. In that situation, this is can be seen as a special kind of WAIT as we're not actually RUNNING (no CPU burn) at all but you'd have to use an OS thread dump rather than a Java thread dump to see it.
Blocked- Your thread is in runnable state of thread life cycle and trying to obtain object lock.
Wait- Your thread is in waiting state of thread life cycle and waiting for notify signal to come in runnable state of thread.
see this example:
demonstration of thread states.
/*NEW- thread object created, but not started.
RUNNABLE- thread is executing.
BLOCKED- waiting for monitor after calling wait() method.
WAITING- when wait() if called & waiting for notify() to be called.
Also when join() is called.
TIMED_WAITING- when below methods are called:
Thread.sleep
Object.wait with timeout
Thread.join with timeout
TERMINATED- thread returned from run() method.*/
public class ThreadBlockingState{
public static void main(String[] args) throws InterruptedException {
Object obj= new Object();
Object obj2 = new Object();
Thread3 t3 = new Thread3(obj,obj2);
Thread.sleep(1000);
System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+
",when Wait() is called & waiting for notify() to be called.");
Thread4 t4 = new Thread4(obj,obj2);
Thread.sleep(3000);
System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2.");
System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called.");
}
}
class Thread3 extends Thread{
Object obj,obj2;
int cnt;
Thread3(Object obj,Object obj2){
this.obj = obj;
this.obj2 = obj2;
this.start();
}
#Override
public void run() {
super.run();
synchronized (obj) {
try {
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait().");
obj.wait();
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait().");
synchronized (obj2) {
cnt++;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Thread4 extends Thread{
Object obj,obj2;
Thread4(Object obj,Object obj2){
this.obj = obj;
this.obj2 = obj2;
this.start();
}
#Override
public void run() {
super.run();
synchronized (obj) {
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify().");
obj.notify();
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify().");
}
synchronized (obj2) {
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

Java Thread Pools/Executor Service and wait()s - what happens to the threads & task queue?

I've looked around but haven't found an answer so I wanted to confirm this for certain.
Say I have a fixed size thread pool - ExecutorService pool = Executors.newFixedThreadPool(5);
And I have some code:
pool.execute(new Runnable(){
try{
Object waitForMe = doSomethingAndGetObjectToWaitFor();
waitForMe.wait();
doSomethingElse();
}catch(Exception e){ throw new RunTimeException(e) }
});
Lets assume that the above code is called a few 100 times. There are only 5 threads in the pool (so only 5 of the above statements should be live at one point). Also assume that the wait() is on an object doing some I/O calls to a thrid party and waiting for a callback when the operation is complete so it will naturally take a while to complete.
Now my question is what is the behavior when one of these tasks reaches a wait(), does the task go to sleep and then the thread from the thread pool takes another task off queue and starts running it?
If the task that is waiting goes to sleep what happens when it gets a notify() and wakes up? Does the thread go back into the queue (at the front or back) for the thread pool and wait until one of the 5 threads can continue to execute it (i.e. call doSomethingelse())? Or does the thread that was executing it also go to sleep i.e. one of the 5 executor threads sits waiting with the task (this is what I'm assuming)? Or does the executor thread pick up another task and simply get interrupted when the first task returns from the wait()?
wait() is a blocking operation:
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll()
This means that the thread in the pool will wait, but from outside it just looks like the current task takes so much time to complete. This also means that if 5 tasks are executed and they all wait(), the Executor cannot handle remaining tasks that, ekhem, wait in the queue.
True, the executor thread itself goes to sleep allowing other threads to switch and consume CPU (so you can have hundreds of threads waiting at the same time and your system is still responsive) but still the thread is "unusable" and blocked.
Another interesting feature is interrupting - if the thread waits for something or sleeps you can interrupt it. Note that both wait() and Thread.sleep() declare InterruptedException. With ExecutorService you can take advantage of this by simply calling: future.cancel() (future is the object you got in return when submit task to ExecutorService).
Finally I think you should redesign your solution. Instead of actively waiting for an external system to finish, provide an API with callbacks:
pool.execute(new Runnable(){
try{
doSomethingAndCallMeBackWhenItsDone(new Callback() {
public void done() {
doSomethingElse();
}
});
}catch(Exception e){ throw new RunTimeException(e) }
});
This way the external system's API will simply notify you when the results are ready and you won't have to wait and block ExecutorService. Finally, if doSomethingElse() takes a lot of time, you might even decide to schedule it as well rather than using external third-party I/O thread:
pool.execute(new Runnable(){
try{
doSomethingAndCallMeBackWhenItIsDone(new Callback() {
public void done() {
pool.submit(new Callbale<Void>() {
public Void call() {
doSomethingElse();
}
}
}
});
}catch(Exception e){ throw new RunTimeException(e) }
});
UPDATE: you are asking what to do about timeouts? Here is my idea:
pool.execute(new Runnable(){
try{
doSomethingAndCallMeBackWhenItsDone(new Callback() {
public void done() {
doSomethingElse();
}
public void timeout() {
//opps!
}
});
}catch(Exception e){ throw new RunTimeException(e) }
});
I guess you can implement timeout on the third-party side and if timeout occurs there, simply call timeout() method.
The wait() cannot know anything about the tread pool. And the thread pool cannot know anything about the wait(). So they cannot interact anyhow.
They work as usual - the wait() just is a long running blocking operation, the thread pool is just a queue of runnables to run on limited pool of threads.
I'd comment on Tomasz's answer but my reputation does not allow it (yet), sorry.
I know the question is old, but for the people that still end up reading this page, have a look at Future and especially guava's ListenableFuture that lets you register callbacks and chain future together with, precisely, the purpose of not blocking your thread (and thus free the thread back to the pool for something else to use it).
All 5 threads will be blocked and application will be in un-productive state.
Adding to Tomasz answer, I would like to implement time out mechanism as follows.
Future<Long> futureResult = service.execute(myCallable);
Long result = null;
try{
result = futureResult.get(5000, TimeUnit.MILLISECONDS);
}catch(TimeoutException e){
System.out.println("Time out after 5 seconds");
futureResult.cancel(true);
}catch(InterruptedException ie){
System.out.println("Error: Interrupted");
}catch(ExecutionException ee){
System.out.println("Error: Execution interrupted");
}
Apart from TimeoutException, you can cancel Future during InterruptedException & ExecutionException. If you use submit() instead of execute(), InterruptedException & ExecutionException will be swallowed in framework itself.

How to interrupt ExecutorService's threads

When using the ExecutorService returned by Executors.newSingleThreadExecutor(), how do I interrupt it?
In order to do this, you need to submit() a task to an ExecutorService, rather than calling execute(). When you do this, a Future is returned that can be used to manipulate the scheduled task. In particular, you can call cancel(true) on the associated Future to interrupt a task that is currently executing (or skip execution altogether if the task hasn't started running yet).
By the way, the object returned by Executors.newSingleThreadExecutor() is actually an ExecutorService.
Another way to interrupt the executor's internally managed thread(s) is to call the shutdownNow(..) method on your ExecutorService. Note, however, that as opposed to #erickson's solution, this will result in the whole ThreadPoolExecutor becoming unfit for further use.
I find this approach particularly useful in cases where the ExecutorService is no longer needed and keeping tabs on the Future instances is otherwise unnecessary (a prime example of this being the exit(..) method of your application).
Relevant information from the ExecutorService#shutdownNow(..) javadocs:
Attempts to stop all actively executing tasks, halts the processing of
waiting tasks, and returns a list of the tasks that were awaiting
execution.
There are no guarantees beyond best-effort attempts to stop processing
actively executing tasks. For example, typical implementations will
cancel via Thread.interrupt, so any task that fails to respond to
interrupts may never terminate.
One proper way could be customizing/injecting the ThreadFactory for the ExecutorService and from within the thread factory, you got the handle of the thread created, then you can schedule some task to interrupt the thread being interested.
Demo code part for the overwrited method newThread in ThreadFactory:
ThreadFactory customThreadfactory new ThreadFactory() {
public Thread newThread(Runnable runnable) {
final Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
scheduledExecutorService.schedule(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executed!");
thread.interrupt();
return "Called!";
}
}, 5, TimeUnit.SECONDS);
return thread;
}
}
Then you can use below code to construct your ExecutorService instance:
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
Then after 5 seconds, an interrupt signal will be sent to the threads in ExecutorService.

Categories

Resources