ExecutorService never stops without Exceptions - java

I adopted a the concurrency strategy from this post. However mine looks like this:
ExecutorService executorService = Executors.newFixedThreadPool(NUMBER_OF_CREATE_KNOWLEDGE_THREADS);
List<Callable<Collection<Triple>>> todo = new ArrayList<Callable<Collection<Triple>>>(this.patternMappingList.size());
for (PatternMapping mapping : this.patternMappingList ) {
todo.add(new CreateKnowledgeCallable(mapping, i++));
}
try {
List<Future<Collection<Triple>>> answers = executorService.invokeAll(todo);
for (Future<Collection<Triple>> future : answers) {
Collection<Triple> triples = future.get();
this.writeNTriplesFile(triples);
}
}
catch (InterruptedException e) { ... }
catch (ExecutionException e) { ... }
executorService.shutdown();
executorService.shutdownNow();
But the ExecutorService never shuts down. I tried to debug how many of the CreateKnowledgeCallable are finished, but this number seems to vary (after no new threads/callables are executed but the service keeps running). I am sure a logged and printed every possible exception but I can't see one happening. It also seems that after a while nothing happens anymore except that NUMBER_OF_CREATE_KNOWLEDGE_THREADS cpus are spinning at 100% forever. What am I doing wrong?
If you need to more specific infos I would be happy to provide them for you!
Kind regards,
Daniel

When you perform a shutdownNow() it interrupts all the threads in the pool. However, if your code ignores interrupts, they won't stop. You need to make your tasks honour interrupts with tests like
while(!Thread.currentThread.isInterrupted()) {
}
or
Thread.sleep(0);

executorService.invokeAll
should return only when all tasks are finished. As well as future.get()
Are you sure, that call to executorService.invokeAll(todo); ever returns and not blocks forever waiting for tasks to complete?

are you sure that you submitted tasks actually finish? If you check the API for shutdownNow() and shutdown() you'll see that they do not guarantee termination.
Have you tried using a call to awaitTermination(long timeout,
TimeUnit unit) with a reasonable amount of time as timeout parameter? (edit: "reasonable amount of time" depends of course on the mean process time of your tasks as well as the number of tasks executing at the time you call for termination)
Edit2: I hope the following example from my own code might help you out (note that it probably isn't the optimal, or most gracious, way to solve this problem)
try {
this.started = true;
pool.execute(new QueryingAction(pcqs));
for(;;){
MyObj p = bq.poll(timeout, TimeUnit.MINUTES); // poll from a blocking queue
if(p != null){
if (p.getId().equals("0"))
break;
pool.submit(new AnalysisAction(ds, p, analyzedObjs));
}else
drc.log("Timed out while waiting...");
}
} catch (Exception ex) {
ex.printStackTrace();
}finally{
drc.log("--DEBUG: Termination criteria found, shutdown initiated..");
pool.shutdown();
int mins = 2;
int nCores = poolSize -1 ;
long totalTasks = pool.getTaskCount(),
compTasks = pool.getCompletedTaskCount(),
tasksRemaining = totalTasks - compTasks,
timeout = mins * tasksRemaining / nCores;
drc.log( "--DEBUG: Shutdown commenced, thread pool will terminate once all objects are processed, " +
"or will timeout in : " + timeout + " minutes... \n" + compTasks + " of " + (totalTasks -1) +
" objects have been analyzed so far, " + "mean process time is: " +
drc.getMeanProcTimeAsString() + " milliseconds.");
pool.awaitTermination(timeout, TimeUnit.MINUTES);
}

Everyone with this sort of problems should try to implement the same algorithm without concurrency. With the help of this method, I found that a component has thrown a runtime exception which was swallowed.

Related

CompletableFuture inside another CompletableFuture doesn't join with timeout

I have one completable future that just runs another completable future(that takes always about 2 seconds and timeout of 50 ms) and waits for it to complete with timeout 1 second.
The problem is timeout of inner future never works, but get works for about two seconds, though it has timeout of 50 ms and consequently outer CompletableFuture time outs.
sleepFor2000Ms calls Thread.sleep(2000)
private static void oneCompletableFutureInsideAnother() throws InterruptedException, ExecutionException{
long time = System.nanoTime();
try{
System.out.println("2 started");
CompletableFuture.runAsync(() -> {
long innerTime = System.nanoTime();
try{
System.out.println("inner started");
CompletableFuture.runAsync(TestApplication::sleepFor2000Ms)
.get(50, TimeUnit.MILLISECONDS); // this get doesn't work
// it waits way longer, until the future completes successfully
System.out.println("inner completed successfully");
}catch(InterruptedException | ExecutionException | TimeoutException e){
System.out.println("inner timed out");
}
long innerTimeEnd = System.nanoTime();
System.out.println("inner took " + (innerTimeEnd - innerTime)/1_000_000 + " ms");
}).get(1, TimeUnit.SECONDS);
System.out.println("2 completed successfully");
}catch(TimeoutException e){
System.out.println("2 timed out");
}
long endTime = System.nanoTime();
System.out.println("2 took " + (endTime - time)/1_000_000 + " ms");
}
Expected output looks like this(and i get this input on java 8):
2 started
inner started
inner timed out
inner took 61 ms
2 completed successfully
2 took 62 ms
Actual output is(i get it on java 9 and higher):
2 started
inner started
2 timed out
2 took 1004 ms
inner completed successfully
inner took 2013 ms
If i do the same job, but inside single CompletableFuture, it time outs correctly:
private static void oneCompletableFuture() throws InterruptedException, ExecutionException{
long time = System.nanoTime();
try{
System.out.println("1 started");
CompletableFuture.runAsync(TestApplication::sleepFor2000Ms)
.get(50, TimeUnit.MILLISECONDS); // this get works ok
// it waits for 50 ms and then throws TimeoutException
System.out.println("1 completed successfully");
}catch(TimeoutException e){
System.out.println("1 timed out");
}
long endTime = System.nanoTime();
System.out.println("1 took " + (endTime - time)/1_000_000 + " ms");
}
Is it intended to work this way or am I doing something wrong or maybe it's bug in java library?
Unlike the Java 8 version, the .get(50, TimeUnit.MILLISECONDS) call of newer versions tries to perform some other pending tasks instead of blocking the caller thread, not considering that it can’t predict how long these tasks may take and hence, by what margin it may miss the timeout goal. When it happens to pick up the very task it’s waiting for, the result is like having no timeout at all.
When I add a Thread.dumpStack(); to sleepFor2000Ms(), the affected environments print something like
java.lang.Exception: Stack trace
at java.base/java.lang.Thread.dumpStack(Thread.java:1380)
at TestApplication.sleepFor2000Ms(TestApplication.java:36)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.helpAsyncBlocker(ForkJoinPool.java:1253)
at java.base/java.util.concurrent.ForkJoinPool.helpAsyncBlocker(ForkJoinPool.java:2237)
at java.base/java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1933)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2095)
at TestApplication.lambda$0(TestApplication.java:15)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.run(CompletableFuture.java:1804)
at java.base/java.util.concurrent.CompletableFuture$AsyncRun.exec(CompletableFuture.java:1796)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
but note that this is a race. It does not always happen. And when I change the inner code to
CompletableFuture<Void> inner
= CompletableFuture.runAsync(TestApplication::sleepFor2000Ms);
LockSupport.parkNanos(1_000_000);
inner.get(50, TimeUnit.MILLISECONDS);
the timeout reproducibly works (this may still fail under heavy load though).
I could not find a matching bug report, however, there’s a similar problem with ForkJoinTask, ForkJoinTask.get(timeout) Might Wait Forever. This also hasn’t been fixed yet.
I would expect that when Virtual Threads (aka project Loom) become reality, such problems will disappear, as then, there is no reason to avoid blocking of threads because the underlying native thread can be reused without such quirks.
Until then, you should rather avoid blocking worker threads in general. Java 8’s strategy of starting compensation threads when worker threads get blocked, doesn’t scale well, so you’re exchanging one problem for another.

Timer issues in java when using Timeout Exceptions, code doesn't run correctly after a Timeout Exception

I'm designing a game in java called that's similar to the board game go. In the implementation there is also a mode called speed mode, where if a player doesn't take a turn within the time limit (5 seconds) the other player is to win. This mode can also be won normally be "capturing" the opposition piece. After either of these conditions is met , the game is to be ran again from the main menu. This works fine in normal mode and in speed mode when the win conditions are met by capturing. When it's won by time running out however it behaves very oddly, almost randomly prompting for input and printing.
The code for the time is as follows:
public Boolean speedMode(Player player, Player opponent) {
ExecutorService service = Executors.newSingleThreadExecutor();
try {
Runnable r = new Runnable() {
Boolean outOfRange;
public void run() {
do {
outOfRange = takeTurn(player);
} while (outOfRange == true);
}
};
Future<?> f = service.submit(r);
f.get(5, TimeUnit.SECONDS);
} catch (final InterruptedException e) {
System.out.println("The thread was interrupted during sleep, wait or join");
} catch (final TimeoutException e) {
player.setWon(false);
System.out.println("\n" + player.getName() +", you took too long... ");
return true;
} catch (final ExecutionException e) {
System.out.println("An exception from within the Runnable task");
}
return false;
}
When the TimeoutException happens the oppisite player wins while loop shown beow is exited and the correct congratulations are printed. The problem is when It starts the new game at the bottom line of code thats when the weird behaviour starts. Is there something I need to close perhaps in the timer method?It's almost like it's still running in the back ground.
else {
do {
timeOut = speedMode(second, first);
if(winCheck1(first) == true || timeOut == true){
break;
}
timeOut = speedMode(first, second);
} while (winCheck1(second) != true && timeOut != true);
if(player1.isWon() == true){
System.out.println("\n\nCongratulations " + player1.getName() + " you are the winner!\n\n");
}
else{
System.out.println("\n\nCongratulations " + player2.getName() + " you are the winner!\n\n");
}
}
//reload the menu
Game game = new Game();
}
Basically my question is; can anyone tell me why starting a new game does not work correctly after throwing a TimeoutException?
Is there something I need to close perhaps in the timer method?It's almost like it's still running in the back ground.
If you don't call shutdown on the executor the worker thread that the executor created will hang around. (This is independent of the scope in which you declared the executor.) If it is a non-daemon thread then it will keep the old JVM alive.
Also your task needs to be responsive to interruption. See the documentation for shutdownNow:
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.
"Responding to interrupts" means checking Thread.currentThread().isInterrupted() to see if the thread has been canceled and then acting on it (finding a stopping place, doing cleanup, and exiting the run method), and restoring the interrupted flag (Thread.currentThread().interrupt()) if an InterruptedException or InterruptedIOException is caught.

How can we make a thread to sleep for a infinite time in java?

Pls help me to understand how can we make a thread to sleep for a infinite time period .
I can't think of a good reason for doing this. As one of the comments noted Long.MAX_VALUE is roughly 292 billion years so probably Thread.sleep(Long.MAX_VALUE) is enough. But if you want a theoretical infinite sleep solution:
while (true) {
Thread.sleep(Long.MAX_VALUE);
}
Literally, you can't. No Java application can run for an infinite amount of time. The hardware will die first :-)
But in practice1, the following will sleep until the JVM terminates ... or the thread is interrupted.
public void freeze() throws InterruptedException {
Object obj = new Object();
synchronized (obj) {
obj.wait();
}
}
If you wanted to you could catch the exception within a while (true) loop. And doing the same with "sleep(max int)" is equivalent.
But frankly, making a thread go to sleep "for ever" is wasteful2, and probably a bad idea. I have no doubt that there will be better ways to achieve what you are really trying to do.
1 - These solutions I talk about are for when a thread needs to make itself go to sleep. If you one thread to unilaterally make a different thread go to sleep, it can't do that safely. You could use the deprecated Thread.suspend() method, but it is dangerous, and it may not be available on future Java platforms.
2 - A thread stack occupies a significant amount of memory, and it cannot be released until the thread terminates.
Thread.currentThread().join();
Will sleep until the JVM is killed.
Make it wait for a mutex or resource that will never be released. It's the deadlock principle. The better way is to make the thread to finish his code, so it will end and not be started again.
Edit:
I don't recommand an infinite loop since it's the pooling principle. It will consume a lot of resources for nothing.
You can use class CyclicBarrier from the JDK.
new CyclicBarrier(2).await();
Constructor argument is the number of threads that must invoke await method before the barrier is reached.
It's actually quite easy if you do it this way:
public static boolean timerController = false;
Timer timer = new Timer();
public TimerTask task = new TimerTask() {
public void run() {
if(timerController == false){
tracker();
t.setText("<html><br/>Day " + day + ", hour " + hour + "<br/>");
System.out.println("Hour: " + hour + " Day: " + day + " Real time seconds " + realTime + " Seconds");}
}
};
public void start() {
timer.scheduleAtFixedRate(task, 1000, 1000);
}
public void pause(){
timerController = true;
}
public void resume(){
timerController = false;
}
Make a timer object in another class, and simply start, pause, and resume with the three methods. It should "stop" when you pause the timer, and you won't need to deal with any exception handling or any try/catch statements!

How do I print summary message after all threads (in a pool) complete? [duplicate]

This question already has answers here:
ExecutorService, how to wait for all tasks to finish
(16 answers)
Closed 5 years ago.
I have a command line application. It runs a loop say 100 times and in the loop schedules a task using a thread. I am using ExecutorService so there are 4 threads running at any time.
After the loop ends, I want to print a summary message. E.g. time taken to complete all 100 tasks. When I stepped through the code the debugger went straight to the summary part, but the other tasks are still running. I understand this is because each thread runs on its own. So how do I print messages only after all threads complete?
ExecutorService exec = Executors.newFixedThreadPool(4);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100; i++) {
Runnable requestHandler = new Runnable() {
#Override
public void run() {
try {
// call task function in here
} catch (Exception ex) {
}
}
};
exec.execute(requestHandler);
}
exec.shutdown();
long endTime = System.currentTimeMillis();
LOGGER.info("******************SUMMARY******************");
LOGGER.info("Time taken : " + ((endTime - startTime)/1000) + " seconds, "
+ ((endTime - startTime)/1000/60) + " minutes");
From the main-thread, you could create another thread that does everything from declaring exec to exec.shutdown();. After creating this thread, you put the main-thread to wait. At the end of the new thread's actions(after exec.shutdown();) you should notify it.
See http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html example copied for brevity
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}
Basically you need to wait until the ExecutorService isTerminated() method returns true. You can use awaitTermination() to that end.
The solution for you based on your code:
ExecutorService exec = Executors.newFixedThreadPool(4);
long start = System.currentTimeMillis();
//Your code
exec.shutdown();
while(true) {
if(exec.isTerminated()) {
long end = System.currentTimeMillis();
System.out.println("Time : " + (end - start));
break;
}
Check this out! It works!

Cyclic barrier Java, How to verify?

I am preparing for interviews and just want to prepare some basic threading examples and structures so that I can use them during my white board coding if I have to.
I was reading about CyclicBarrier and was just trying my hands at it, so I wrote a very simple code:
import java.util.concurrent.CyclicBarrier;
public class Threads
{
/**
* #param args
*/
public static void main(String[] args)
{
// ******************************************************************
// Using CyclicBarrier to make all threads wait at a point until all
// threads reach there
// ******************************************************************
barrier = new CyclicBarrier(N);
for (int i = 0; i < N; ++i)
{
new Thread(new CyclicBarrierWorker()).start();
}
// ******************************************************************
}
static class CyclicBarrierWorker implements Runnable
{
public void run()
{
try
{
long id = Thread.currentThread().getId();
System.out.println("I am thread " + id + " and I am waiting for my friends to arrive");
// Do Something in the Thread
Thread.sleep(1000*(int)(4*Math.random()*10));
// Now Wait till all the thread reaches this point
barrier.await();
}
catch (Exception e)
{
e.printStackTrace();
}
//Now do whatever else after all threads are released
long id1 = Thread.currentThread().getId();
System.out.println("Thread:"+id1+" We all got released ..hurray!!");
System.out.println("We all got released ..hurray!!");
}
}
final static int N = 4;
static CyclicBarrier barrier = null;
}
You can copy paste it as is and run in your compiler.
What I want to verify is that indeed all threads wait at this point in code:
barrier.await();
I put some wait and was hoping that I would see 4 statements appear one after other in a sequential fashion on the console, followed by 'outburst' of "released..hurray" statement. But I am seeing outburst of all the statements together no matter what I select as the sleep.
Am I missing something here ?
Thanks
P.S: Is there an online editor like http://codepad.org/F01xIhLl where I can just put Java code and hit a button to run a throw away code ? . I found some which require some configuration before I can run any code.
The code looks fine, but it might be more enlightening to write to System.out before the sleep. Consider this in run():
long id = Thread.currentThread().getId();
System.out.println("I am thread " + id + " and I am waiting for my friends to arrive");
// Do Something in the Thread
Thread.sleep(1000*8);
On my machine, I still see a burst, but it is clear that the threads are blocked on the barrier.
if you want to avoid the first burst use a random in the sleep
Thread.sleep(1000*(int)(8*Math.rand()));
I put some wait and was hoping that I
would see 4 statements appear one
after other in a sequential fashion on
the console, followed by 'outburst' of
"released..hurray" statement. But I am
seeing outburst of all the statements
together no matter what I select as
the sleep.
The behavior I'm observing is that all the threads created, sleep for approximately the same amount of time. Remember that other threads can perform their work in the interim, and will therefore get scheduled; since all threads created sleep for the same amount of time, there is very little difference between the instants of time when the System.out.println calls are invoked.
Edit: The other answer of sleeping of a random amount of time will aid in understanding the concept of a barrier better, for it would guarantee (to some extent) the possibility of multiple threads arriving at the barrier at different instants of time.

Categories