LinkedBlockingQueue.poll(...) occasionally throwing an InterruptedException - java

I'm using a java 1.8 java.util.concurrent.LinkedBlockingQueue, and when I call:
LinkedBlockingQueue.poll(5000, TimeUnit.MILLISECONDS)
it is very occasionally throwing an InterruptedException:
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.reportInterruptAfterWait(AbstractQueuedSynchronizer.java:2014)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2088)
at java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467)
which I think is happening because the following is returning true during the (indirect) call to checkInterruptWhileWaiting() at AbstractQueuedSynchronizer:2079
Unsafe.compareAndSwapInt(...)
As a side note, Unsafe.compareAndSwapInt returns a boolean, but what does that boolean mean? I can't find any documentation on that Class/function.
I suspect that something is going on in another thread to cause this issue, but I'm not sure where to look right now.
Any help on understanding why the InterruptedException is being thrown would be very helpful. I would really like to be able to reproduce it in a small test program, but it's in a big messy program right now so I'm trying to understand what things could cause this so that I can create a test program to reproduce it.

Is there any other thread in your app that calls Thread.interrupt()? This is what's happening in awaitInNanos():
if (Thread.interrupted())
throw new InterruptedException();
If you control the threads, then you can override the interrupt method just for testing:
Thread thread = new Thread() {
#Override
public void run() {
// do something longrunning
}
#Override
public void interrupt() {
// try-finally ensures to run both super.interrupt() and the deubg code
try {
super.interrupt();
} finally {
// you can use any logging services that you already have
System.out.println("--> Interrupted from thread: " + Thread.currentThread().getName());
Thread.dumpStack();
}
}
};
If you create the threads manually, you can override interrupt(). If you use executors, then you can provide a ThreadFactory, that creates the threads with the right interrupt() method.
Here is a main() method that plays with this debug technique. Please note that you need to enter a line in STDIN or manually kill the process. Otherwise it's going to run forever (jvm restart).
public static void main(String[] args) {
Thread thread = new Thread() {
#Override
public void run() {
System.out.println("--> asdf");
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
br.readLine();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
#Override
public void interrupt() {
// try-finally ensures to run both super.interrupt() and the deubg code
try {
super.interrupt();
} finally {
// you can use any logging services that you already have
System.out.println("--> Interrupted from thread: " + Thread.currentThread().getName());
Thread.dumpStack();
}
}
};
thread.start();
System.out.println("--> before interrupt");
thread.interrupt();
System.out.println("--> after interrupt");
}

Related

Why is the statement in finally block still executed?

public class ADaemon implements Runnable {
#Override
public void run() {
try {
System.out.println("Starting ADaemon");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Exiting via InterruptedException");
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}}
result
Starting ADaemon
Exiting via InterruptedException
This should always run?
I tried to the code sample from "Thinking in Java" 4th edition, but it did't get the result as described in the book, the finally block is still being executed, why is that so? BTW I am using oracle jdk 10.0.1.
-------------update----------
It seems there is something run with my maven-runner plugin, I disabled it and it just get the same result as described in the book.
You say that the book says:
"the finally block may not be executed".
(Emphasis added.)
That is not the same as saying:
"the finally block will not be executed".
I think that the book is implying that it is unspecified (and possibly JVM specific) whether daemon thread gets an interrupt (or something) when the application exits.
Certainly, if the daemon thread caught and ignored the "interrupted" exception as follows, then I would expect that the finally to never be executed.
public class ADaemon implements Runnable {
#Override
public void run() {
try {
System.out.println("Starting ADaemon");
while (true) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
System.out.println("Caught InterruptedException");
}
}
} finally {
System.out.println("This should always run?");
}
}
public static void main(String... args) {
Thread t = new Thread(new ADaemon());
t.setDaemon(true);
t.start();
}
}
I would expect similar behavior if the daemon thread was not executing interruptible code.
This should always run? Yes. Unless the JVM actually halts the finally block is guaranteed to be entered. Something like
System.exit(-1);
in the catch block will prevent that. If that is what you want. It will also stop the JVM! The book is warning you that if all other threads are completed, the daemon thread may never be scheduled before the JVM terminates. You are directly calling start(). Consider using
SwingUtilities.invokeLater(t);
It probably won't run unless you remove t.setDaemon(true);
The finally block is a powerful (and dangerous if used incorrectly) tool which will almost always run after the try or catch block completes (despite some small cases which are highlighted above).
Look at this example:
try{
throw new Exception();
}catch(Exception e){
return;
}finally{
System.out.println("Shouldn't run?");
}
If this was in a method, the finally block would still be executed (never do this as it is a bad practise). It is designed to perform any cleanup despite the result of the operation you did such as closing streams (which can now be done automatically through paranthesis in the statement 'try').

What is wrong with it?

I've seen a lot of example for wait and notify, but still I have a problem.
public class Main(){
public static void main(String args[]) throws Exception {
MyThread s = new MyThread();
s.start();
}
}
class MyThread extends Thread {
public void run() {
k();
}
public synchronized void k() {
System.out.println("before wait");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("do something after wait");
}
public synchronized void m() {
for (int i=0;i<6;i++)
System.out.println(i);
notify();
}
}
The only output I get when run the program is: "before wait".
The thread you create in main invokes MyThread#k() which goes into a wait. At that point, that thread will do nothing else until it is awakened or interrupted. But the only place in your code where it could possibly be awakened is the notify in MyThread#m(). Since nothing in your program calls that method, the thread can never be awoken.
What you probably want is to add a call to s.m() right after s.start() in your main program. That way your main thread will execute the notify that's needed to wake up your thread.
Unfortunately, that's very unlikely to work. The problem is that s.start() causes your created thread to become ready to run, but it doesn't necessarily run immediately. It could well happen that your call to s.m() will complete before the created thread does anything. And then you'll still have exactly the same result as before, except that you'll see the integers 0..6 printed out before before wait. The notify will do nothing, because the child thread has not yet performed its wait. (And by the way, since both MyThread#k() and MyThread#m() are both synchronized, increasing your loop limit in MyThread#m() won't change a thing... the child thread won't be able to enter MyThread#k() while MyThread#m() is running. You could improve that by putting the notify in a sycnchronized block rather than making all of MyThread#m() synchronized.)
You can try to get around this by adding Thread.sleep(1000) before s.m() in your main program. That will almost certainly work because your main thread will yield execution, giving your JVM the opportunity to schedule the child thread for some useful work. By the time the main thread wakes out of its sleep and performs its s.m() call, the child will probably have executed its wait and you will then see your do something after wait message.
But that's still pretty crummy, because it still depends on scheduling events that you don't really have any control over. There's still no guarantee that the wait will happen before the notify.
This is why when using wait/notify you should generally arrange for there to be some sort of reliable test as to whether whatever you're waiting to be done has actually occurred. This should be a condition that, once it turns turns true, will remain true at least until the test has been subsequently performed. Then your typical wait loop looks something like this:
while (!isDone()) {
synchronized(monitorObject) {
try {
monitorObject.wait();
} catch (InterruptedException e) {
}
}
}
Putting the whole thing in a loop takes care of premature waking, e.g. due to InterruptedException.
If the required work has already occurred by the time this code is executed, no wait occurs, and the notify executed by the code that did the work was a no-op. Otherwise, this code waits, and the code completing the work will eventually do a notify which will wake this code up as required. Of course, it's critical that, at the time the notify is performed, the wait condition (isDone() above) be true and remain true at least until tested.
Here's a corrected version of your code that incorporates a proper wait loop. If you comment out the Thread.sleep() call, you will likely not see the waiting message, because the work will complete before the wait loop even starts. With the sleep included, you'll probably see the waiting message. But either way, the program will work properly.
public static void main(String[] argv) throws Exception {
MyThread s = new MyThread();
s.start();
Thread.sleep(1000);
s.m();
}
class MyThread extends Thread {
#Override
public void run() {
k();
}
private boolean done = false;
public void k() {
System.out.println("before wait");
while (!done) {
System.out.println("waiting");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
System.out.println("do something after wait");
}
public void m() {
for (int i = 0; i < 6; i++) {
System.out.println(i);
}
synchronized (this) {
done = true;
notify();
}
}
}
The problem is, that you're not calling your m method, so notify is never called, so your thread sleeps forever. You could call it in main, after the start, using s.m():
MyThread s = new MyThread();
s.start();
s.m();
Maybe you should sleep for a little time before calling the m method, as it could run sooner than k in the thread:
s.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// nothing to do
}
s.m();
Not closely related to the question, but a throws declaration in main is not very advisable, even a generated printStackTrace is better than throwing the exception away.

Stop thread and again start giving IllegalThreadStateException in blackberry

I am getting IllegalThreadStateException exception when using following code:
I have already started this thread once(by using thread.start()) and again trying to start it at another place, so used following code:
thread.interrupt();
thread.start();
But thread.start() is throwing IllegalThreadStateException.
What should I use to solve it?
Thread objects are only meant to be started once. If you need to stop/interrupt a Thread, and then want to start it again, you should create a new instance, and call start() on it:
thread.interrupt(); // if you need to make sure thread's run() method stops ASAP
thread = new MyThreadSubclass();
thread.start();
From the API docs
IllegalThreadStateException - if the thread was already started.
I know it's not 100% clear that you can't call start() again, even if you previously called interrupt(), but that's the way it works.
If you look at the API docs for standard Java, this issue is more clear.
In addition to Nate's answer.
AnkitRox states in his comment:
Thanks Nate. I was also trying your method. But the problem occurred at that time was, it was start a new thread for the new instance and previous thread was also working.
So it looks like the problem is "the thread is still running even if I called interrupt on it". Consider this sample (it is ugly, but enough to show the main idea):
final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
for (int i = 0; i < 100000000; i++); // simulate some action
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
Note, the thread continues to run even after interrupt() has been called. The produced output is:
hi, interrupted = false
hi, interrupted = true
hi, interrupted = true
hi, interrupted = true
...
hi, interrupted = true
Actually the programm never stops unless closed forcefully. So what then the interrupt() does? It just sets the interrupted flag to true. After interrupt() has been called the Thread.currentThread().isInterrupted() starts to return false. And that's all.
Another case is if interrupt() is called while the thread is blocked in an invocation of one of the methods that throw InterruptedException, then that method will return throwing the InterruptedException. And if thread's code just "eats" that exception, then the thread will still continue running, consider a sample:
final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("got InterruptedException");
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
Note, the thread continues to run even after interrupt() has been called. The produced output is:
hi, interrupted = false
got InterruptedException
hi, interrupted = false
hi, interrupted = false
...
hi, interrupted = false
Note, this time interrupted = false even after interrupt() has been called. This is because whenever InterruptedException is caught, the interrupted flag is reset to false.
In Java stopping a thread is cooperative mechanism. Meaning it can not be done without cooperation from the thread itself. Here is the fixed version of the above sample:
final Thread t = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("we've been interrupted");
// restore the interrupted flag
Thread.currentThread().interrupt();
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
So the correct approach should be to periodically check the interrupted flag. And if interrupted status is detected then just return ASAP. Another common option is not to use Thread.interrupt() at all, but some custom boolean instead.

What are the circumstances under which a finally {} block will NOT execute?

In a Java try{} ... catch{} ... finally{} block, code within the finally{} is generally considered "guaranteed" to run regardless of what occurs in the try/catch. However, I know of at least two circumstances under which it will not execute:
If System.exit(0) is called; or,
if an Exception is thrown all the way up to the JVM and the default behavior occurs (i.e., printStackTrace() and exit)
Are there any other program behaviors that will prevent the code in a finally{} block from executing? Under what specific conditions will the code execute or not?
EDIT: As NullUserException pointed out, the second case is actually not true. I thought it was because the text in standard error printed after that in standard out, preventing the text from being seen without scrolling up. :) Apologies.
If you call System.exit() the program exits immediately without finally being called.
A JVM Crash e.g. Segmentation Fault, will also prevent finally being called. i.e. the JVM stops immediately at this point and produces a crash report.
An infinite loop would also prevent a finally being called.
The finally block is always called when a Throwable is thrown. Even if you call Thread.stop() which triggers a ThreadDeath to be thrown in the target thread. This can be caught (it's an Error) and the finally block will be called.
public static void main(String[] args) {
testOutOfMemoryError();
testThreadInterrupted();
testThreadStop();
testStackOverflow();
}
private static void testThreadStop() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
#Override
public void run() {
thread.stop();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testThreadInterrupted() {
try {
try {
final Thread thread = Thread.currentThread();
new Thread(new Runnable() {
#Override
public void run() {
thread.interrupt();
}
}).start();
while(true)
Thread.sleep(1000);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testOutOfMemoryError() {
try {
try {
List<byte[]> bytes = new ArrayList<byte[]>();
while(true)
bytes.add(new byte[8*1024*1024]);
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow() {
try {
try {
testStackOverflow0();
} finally {
System.out.print("finally called after ");
}
} catch (Throwable t) {
System.out.println(t);
}
}
private static void testStackOverflow0() {
testStackOverflow0();
}
prints
finally called after java.lang.OutOfMemoryError: Java heap space
finally called after java.lang.InterruptedException: sleep interrupted
finally called after java.lang.ThreadDeath
finally called after java.lang.StackOverflowError
Note: in each case the thread kept running, even after SO, OOME, Interrupted and Thread.stop()!
Infinite loop in the try block.
Corrupt RAM? Program no longer runs as written? I've actually debugged that once on a DOS machine.
Testing the finally block in different statement in try block.
public static void main(String [] args){
try{
System.out.println("Before Statement");
/*** Statement ***/
System.out.println("After Statement");
}
catch(Exception e){
}
finally{
System.out.println("Finally is Executed");
}
Statements in which finally block is executed are following:
Thread.currentThread().interrupted();
Thread.currentThread().destroy();
Thread.currentThread().stop();
Thread.sleep(10);
Thread.currentThread().interrupt();
Runtime.getRuntime().addShutdownHook(Thread.currentThread());
If there is any exception occurred.
If there is no exception.
Statements in which finally block is not executed are following:
Thread.currentThread().suspend();
System.exit(0);
JVM crashed.
Power to CPU chip goes off.
OS kills JVM process.
Runtime.getRuntime().exit(0);
Runtime.getRuntime().halt(0);
There is a chance of partial execution when finally itself throws an exception (or leads to an error)
One could be "A finally is a part of daeomon thread it may not be executed".
The only times finally won't be called are:
if the power turns off
if you call System.exit()
if the JVM crashes first
if there is an infinite loop in the try block
if the power turns off
I think when JVM exits suddenly due to any reason, that can be a cause the control will not enter into the the finally block and never execute.
You can make it a part of Daemon Thread. You may use the method setDaemon(boolean status) which is used to mark the current thread as daemon thread or user thread and exit the JVM as and when required. This will enable you exit the JVM before finally{} is executed.
Another possible instance of a finally block never executing would be due to a design where the method returned before the try block was entered, as in the cases of some very bad code I've seen from time to time:
public ObjectOfSomeType getMeAnObjectOfSomeType() throws SomeHorrendousException {
if (checkSomeObjectState()) {
return new ObjectOfSomeType();
}
try {
// yada yada yada...
} catch (SomeHorrendousException shexc) {
// wow, do something about this horrendous exception...
} finally {
// do some really important cleanup and state invalidation stuff...
}
I know none of you would ever do this, so I hesitated to add this as a possible scenario, but thought, eh, it's Friday, what the heck ; )

Multithreading problem using System.out.print vs println

I have the following thread which simply prints a dot every 200ms:
public class Progress {
private static boolean threadCanRun = true;
private static Thread progressThread = new Thread(new Runnable()
{
public void run() {
while (threadCanRun) {
System.out.print('.');
System.out.flush();
try {
progressThread.sleep(200);
} catch (InterruptedException ex) {}
}
}
});
public static void stop()
{
threadCanRun = false;
progressThread.interrupt();
}
public static void start()
{
if (!progressThread.isAlive())
{
progressThread.start();
} else
{
threadCanRun = true;
}
}
}
I start the thread with this code (for now):
System.out.println("Working.");
Progress.start();
try {
Thread.sleep(10000); //To be replaced with code that does work.
} catch (InterruptedException ex) {}
Progress.stop();
What's really strange is this:
If I use System.out.println('.'); , the code works exactly as expected. (Apart from the fact that I don't want a new line each time).
With System.out.print('.');, the code waits for ten seconds, and then shows the output.
System.out.println:
Print dot, wait 200ms, print dot, wait 200ms etc...
System.out.print:
Wait 5000ms, Print all dots
What is happening, and what can I do to go around this behaviour?
EDIT:
I have also tried this:
private static synchronized void printDot()
{
System.err.print('.');
}
and printDot() instead of System.out.print('.');
It still doesn't work.
EDIT2:
Interesting. This code works as expected:
System.out.print('.');
System.out.flush(); //Makes no difference with or without
System.out.println();
This doesn't:
System.err.print('.');
System.err.flush();
System.out.print('.');
System.out.flush();
Solution: The issue was netbeans related. It worked fine when I run it as a jar file from java -jar.
This is one of the most frustrating errors I have seen in my life. When I try to run this code with breakpoints in debug mode, everything works correctly.
The stdout is line buffered.
Use stderr, or flush the PrintStream after each print.
(This is weird code -- there are much cleaner ways to write and manage threads. But, that's not the issue.)
Your IDE must be buffering by line. Try running it directly on the command line. (And hope that the shell isn't buffering either, but shouldn't.)
The println method automatically flushes the output buffer, the print method not. If you want to see the output immediately, a call to System.out.flush might help.
I think this is because the println() method is synchronized
(This is not an answer; the asker, David, requested that I follow up on a secondary point about rewriting the threading. I am only able to post code this way.)
public class Progress {
private ProgressRunnable progressRunnable = new ProgressRunnable();
public void start() {
new Thread(progressRunnable).start();
}
public void stop() {
progressRunnable.stop();
}
private class ProgressRunnable implements Runnable {
private final AtomicBoolean running = new AtomicBoolean(true);
#Override
public void run() {
while (running.get()) {
System.out.print('.');
System.out.flush();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
}
}
}
private void stop() {
running.set(false);
}
}
public static void main(String[] args) {
Progress progress = new Progress();
progress.start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}
progress.stop();
}
}
I tested your code, with System.out.print() and System.out.flush(). The code works for me, except for the code:
while (!threadCanRun)
{
Thread.yield();
}
in Progress class. Doing that, the thread is pausing allowing other thread to execute, as you can see in the thread api page. Removing this part, the code works.
But I don't understand why do you need the yield method. If you call Progress.stop(), this will cause to invoke the yield method. After the thread will stop with interrupt, (after waiting a huge amount of time on my pc).
If you want to allow other threads executing and the current thread pausing, consider the join() method.
If you want to stop the current thread, maybe you can consider to remove the
while(!threadCanRun) loop, or place Thread.currentThread().join() before Thread.interrupt() in the stop() method to wait for the completion of other threads, or simply call the p.stop() method .
Take a look to these posts.

Categories