I have an implementation of a method that I want to test.
#Override
public void onMessage(final Message message) {
try {
LOG.fine("waiting on semaphore for " + message);
semaphore.acquire();
LOG.fine("semaphore acquired for " + message);
listener.onMessage(message);
LOG.fine(message + " processed");
} catch (final InterruptedException e) {
throw new RuntimeException(e);
} finally {
semaphore.release();
}
}
However, I am not sure how to rigger the InterruptedException from a JUnit test. In theory I can add hooks to terminate it, but that would pollute the code base with code only used for testing which I would like to avoid.
you should mock the semaphore. your faked semaphore should throw the InterruptedException
In my testing interrupting the current thread before calling onMessage, will cause the acquire method to throw even if it didn't need to block, but I don't know if that will happen in all jres.
The other option is to use multiple threads for this.
Have thread one call onMessage, and in it's listener signal thread two to call onMessage and then block until thread 2 is complete.
Have thread two block until thread one has a lock on the semaphore. Then it should interrupt itself and call onMessage. Once it gets the expected runtime exception, it should signal thread one to stop blocking.
I'd use two CountDownLatches to have the two threads communicate.
Make sure you terminate both threads if the test fails.
Related
I have a function in Java. It normally returns a value after it completes its task. However, in some conditions it returns nothing. I create a runnable and run this function as a thread. However, because of its not returning a value, it does not finish although it does its task. The process stays alive because it waits a returning value. Is there a way to kill this thread after it is triggered or after a timeout? Stop() or Destroy() did not work. During debug, the thread is seen as alive and I want it to bi deleted/removed
Runnable runnable = new Runnable() {
#Override
public void run() {
int stat = RunMyFunction();
}
};
Thread thread = new Thread(runnable);
thread.start();
Java does not support killing a thread via any method on java.lang.Thread.
stop() and destroy() do look promising at first glance, but they have both been deprecated.
The documentation for destroy states:
This method was originally designed to destroy this thread without any cleanup. However, the method was never implemented. If if were to be implemented, it would be deadlock-prone
and stop:
This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior.
Thus when the documentation says 'deprecated', what it really means is that they are broken and must never be used!?! The Java API designers put a lot of work into backwards compatibility of their APIs, where other languages would have removed these methods Sun decided to keep them as their internal guides (rightly or wrongly) do not permit the removal of a public api method.
So, the question remains. How is one to get a thread to exit from another thread? Sadly one must go out of ones way to poll an exit variable. This can be a custom variable, or it can be a standard flag within java.lang.Thread that is accessible via 'interrupted()'. The advantage of using interrupted() is that other Java APIs such as IO support this flag during otherwise blocking API calls and will exit throwing an InterruptedException. The detection of calling interrupt() is not immediate, as it sets a flag and relies on the Thread to poll the variable at some point in the future.
Oracle offers a tutorial on how to code using interrupt here.
The real problem you have is that RunMyFunction sometimes never terminates. As others have already stated, killing a thread is not intended in Java, so there is no good way to do it. Instead, you should reason about why you call a possibly non-terminating method. This looks like a code smell. Do the following:
If you are the author of RunMyFunction, make sure that it always terminates or it can be interrupted. You can do this by checking Thread.currentThread().isInterrupted() and throwing an InterruptedException when it is. E.g:
void run(){
while(...){ // this loop sometimes runs forever
if(Thread.currentThread().isInterrupted())
throw new InterruptedException(); // Now, we can "kill" this thread here
}
}
Using ExecuterService you can specify a timeout.
ExecutorService executor = Executors.newFixedThreadPool(1);
List<Callable<String>> tasks = new ArrayList<Callable<String>>();
tasks.add(new Callable<String>() {
#Override
public String call() throws Exception {
int stat = RunMyFunction();
return "Execution Finished";
}
});
new Thread(new Runnable() {
#Override
public void run() {
try {
executor.invokeAll(tasks, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
invokeAll(...) is a blocking call so i've added inside a new thread.
Solution 1: Timed run: If you want a method to return or throw an exception after a specified amount of time, use the following method to execute the method on a background thread while waiting for it to complete:
public static void timedRun(Runnable r, long timeout, TimeUnit unit)
throws InterruptedException, TimeoutException {
Future<?> task = executor.submit(r);
try {
task.get(timeout, unit);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
} finally {
task.cancel(true);
}
}
private static RuntimeException launderThrowable(Throwable t) {
if (t instanceof RuntimeException) return (RuntimeException)t;
else if (t instanceof Error) throw (Error)t;
else throw new IllegalStateException("Not unchecked", t);
}
(Source: Goetz, Brian, Bloch, Joshua, Bowbeer, Joseph, Lea, Doug, Holmes, David and Peierls, Tim. Java Concurrency in Practice. : Addison-Wesley Longman, Amsterdam, 2006. Listing 5.13 and 7.10)
For executor, you can either create a new one using Executor.newSingleThreadExecutor(), or reuse an existing one.
But be warned: Although this method is guaranteed to return or throw an exception after the specified timeout, it cannot guarantee that the runnable will really stop! It interrupts the executing thread, but if the runnable does not react to thread interruption (e.g. by internally checking Thread.interrupted()), it may continue to run in the background - possibly forever - occupying a thread! But at least it does not block.
Solution 2: Timed run with custom threads: If there is any possibility beside thread interruption to cancel your method call, you can still use the approach above, but then you have to use an Executor with custom ThreadFactory that creates a special Thread instance with overridden interrupt method:
Executor executor = Executor.newSingleThreadExecutor(r -> new WsdlThread(r));
public class WsdlThread extends Thread {
public WsdlThread(Runnable r) { super(r); }
public void interrupt() {
try {
// TODO: do something that will interrupt the wsdl call
// e.g. close connection to server, etc.
// example: ((WsdlRunnable)r).getWsdlConnection().close();
} finally {
super.interrupt();
}
}
}
If this isn't possible too, and Thread.stop() doesn't work either, this last solution might work:
Solution 3: Start non-cancellable call in another JVM:
Use Runtime.exec to start another JVM and execute the method call there (See Executing a Java application in a separate process for more info on how to do this). Runtime.exec will return a Process object, which represents the running process.
You can kill it by calling destroy() or destroyForcibly().
try
{
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
I understand what the first part is doing. But what is the catch part waiting for? Like what needs to happen to execute this part.
Every piece of code is run by a "thread". You can think of that as a little virtual processor dedicated to running that particular piece of code.
By calling the Thread.sleep() method, you put this thread in the WAITING state for a certain amount of time. While WAITING, the thread cannot do anything, and in particular, it cannot "hear" calls from other threads.
The only way to wake up the thread and having it run its code again, is to sent it an interruption, which is a very strong signal. This is done by calling the interrupt() method of this thread, from another thread.
When waked up, the thread goes to the RUNNING state again, but to signal the developer that it was waked up earlier than expected, it throws an InterruptedException, which is a checked exception. This is why you have to catch it and deal with it.
The sleep method halts execution of the current thread, in your case 5000 milliseconds (5 seconds). This method however throws InterruptedException which has to be caught.
Because the Thread#sleep() method is defined to throw an InterruptedException under some circumstances, the developer should take care of it when this exact exception occurs. This is why the catch block is needed - to hold the logic which handles the InterruptedException
You thread is going to sleep for 5 seconds.
If another thread tries to wake this thread up (Interrupt). It will end up in the exception block and your stacktrace will be printed.
public class InterruptedException
extends Exception
Thrown when a thread is waiting, sleeping, or otherwise occupied, and
the thread is interrupted, either before or during the activity.
Occasionally a method may wish to test whether the current thread has
been interrupted, and if so, to immediately throw this exception.
Best Explanation is Given ╠══ HERE
If InterruptedException throws(Thread interruption may cause this) from try block that will catch by catch block and as you define in the catch block,it will print the Exception stack trace.
If the Thread is interrupted then it will throw the exception and it will be catched in the catch block.
This is relevant to multithreaded applications.When you have reference to an object of a class that either implements Runnable or extends Thread, and inside that object, a Thread.sleep(i) method has been idling the process, you can call reference.interupt() on that reference and it will trigger the InterruptedException. Here's an example:
In the below code, the Scratch class's run method goes to sleep for 60000 ms (or 1 minute) and prints "I've been interrupted" if it receives an InterruptedExection. The way the code is written, it will not receive this exception and will sleep the entire time. But run it a second time with the line //scratch.interrupt(); uncommented and see what happens.
package scratch;
/**
*
* #author bstidham
*/
public class Scratch extends Thread {
public void run() {
System.out.println("Hello from a thread!");
System.out.println("Going to sleep for 1 minute...");
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
System.out.println("I've been interrupted!");
}
System.out.println("Awake now");
}
public static void main(String args[]) {
Scratch scratch = new Scratch();
scratch.start();
//scratch.interrupt();
}
}
I have a java implementation of a monitor using
java.util.concurrent.locks.Lock;
java.util.concurrent.locks.ReentrantLock;
java.util.concurrent.locks.Condition;
The problem that I'm solving is a readers/writers problem. I have one lock lock & two conditions readers and writers.
I've noticed that the Condition.await() function throws InterruptedException. For now, I've just surrounded the method with a try / catch block. However, the catch block is empty.
I'm wondering when this exception is thrown and how I should be dealing with it.
readers.await() is called when there is a writer writing to a file / there are writers waiting to write to a file.
writers.await() is called when there are one or more readers reading from a file OR a writer is currently writing to a file.
In what cases will InterruptedException be thrown, and how should I deal with them?
Interrupting allows to stop some long/blocking tasks in context of a thread. InterruptedException happens only when someone has set "is interrupted" flag for the given thread.
Now regarding await(). When your thread A is waiting on Condition.await(),usually this means it is parked by
LockSupport.park(Object blocker); (-> sun.misc.Unsafe.park(boolean bln, long l) for Hotspot). Something like this:
public void await() throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
while (still_waiting) {
LockSupport.park(this);
if (Thread.interrupted()) {
throw new InterruptedException();
}
}
}
Now let's assume the user stops the application. The main thread calls A.interrupt() to finish your thread A. interrupt() is implemented in native Thread.interrupt0(). This call set "is interrupted" flag of the thread and unparks the thread A and the thread sees that it is interrupted and throws InterruptedException.
It depends on system requirements how to catch the InterruptedException. If your thread does some work in the loop, you should break the loop to let the thread to be finished. Also, it is good practice to set "is interrupted" flag back for the current thread if you've just catch an InterruptedException:
try {
...
some.await();
}
catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
An old but still good article: http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html?ca=drs-
I am very confused and not able to understand why InterruptedException should not be swallowed.
The article from IBM says
When a blocking method detects interruption and throws InterruptedException, it clears the interrupted status. If you catch InterruptedException but cannot rethrow it, you should preserve evidence that the interruption occurred so that code higher up on the call stack can learn of the interruption and respond to it if it wants to
public class TaskRunner implements Runnable {
private BlockingQueue<Task> queue;
public TaskRunner(BlockingQueue<Task> queue) {
this.queue = queue;
}
public void run() {
try {
while (true) {
Task task = queue.take(10, TimeUnit.SECONDS);
task.execute();
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();//preserve the message
return;//Stop doing whatever I am doing and terminate
}
}
}
Also,Java Concurrency in Practice discusses this in more detail in Chapter 7.1.3: Responding to Interruption. Its rule is:
Only code that implements a thread's interruption policy may swallow an interruption request. General-purpose task and library code should never swallow interruption requests.
1.Can anyone explain how can code in higher call stack make use of the status set by Thread.currentThread().interrupt(); in catch block when the thread is terminated?
Also Please explain the above rule?
Take a look at this example which let's assume runs in a thread/thread-pool context.
public void run() {
// Honor interrupts so that you can stop/kill the task
while (!Thread.currentThread().interrupted()) {
this.doSomeChunkOfWork();
}
}
The above code is a good example of how you would write a task which can be interrupted and processes data in chunks (think of reading from some source and processing data in parts). Now let's assume doSomeChunkOfWork is interrupted and you catch an exception. Unless you set the flag again or maintain the interrupt status of the flag, the run method won't be able to know that the processing deep down the call stack was interrupted when the method call returns which messes up our good logic.
This is the reason why you always set the status back so that methods down the call stack are aware of whether the thread was really interrupted or not. An analogy I would like to think for this is "don't sweep dirt under the rug". :)
In Java thread, the 'run' method cannot throw a 'checked exception'. I came across this in the Core Java (vol 1) book. Can someone please explain the reasoning behind it?
Can someone please explain the reasoning behind it?
Yes, because any exception you throw in run method will be carefully ignored by JVM. Thus, throwing it there is probably a mistake (unless you have specific exception handler for the thread, see the docs about that). No reason to incite potentially erroneous behaviour.
Or, with an example.
class MyThread extends Thread {
public void run() {
throw new RuntimeException();
}
}
...
new MyThread().start();
// here thread dies silently with no visible effects at all
edit
Why can't the parent thread 'catch' the exception from the spawned 'child' thread?
#chaotic3quilibrium has already noted in his comment why not: because parent thread has likely moved on already.
new MyThread().start(); // launch thread and forget
// 1000 lines of code further...
i = i + 1; // would you like exception from child thread to be propagated here?
What would catch the exception and handle it? Let's assume that the run method could throw a checked exception. Then you could write code like this:
Thread myThread = new Thread(aRunnable);
try{
myThread.start();
}
catch(Exception e){
e.printStackTrace();
}
//do other stuff
BUT once you call myThread.start, the new thread is started in the background and the current thread continues and exits the try-catch and does other stuff. So if myThread did throw an exception later on, you can't catch it!
What you need to do is deal with the exception within the run method and then probably have a way of notifying another object that this thread failed.
Suppose thread A starts up thread B. Then thread B throws an exception. You might think it would be nice for thread A to catch it. But where? By the time thread B thows the exception, who knows what thread A is doing? To take a trivial example, suppose we have this code in thread A:
try
{
threadB=new PurgeAbandonedCarts();
threadB.start();
}
catch (NullPointerException panic)
{
... handle errors purging abandoned carts ...
}
try
{
processNewOrders();
}
catch (NullPointerException panic)
{
... handle problems in new orders ...
}
finally
{
... clean up ...
}
So we start up thread B to purge abandoned carts. Once it gets starte, we move on to processing new orders. Then thread B throws a null pointer exception. Should it be caught by the catch block associated with thread B, or the one associated with processing new orders?
If it goes to the new orders catch, it's likely that any code here has nothing to do with cleaning up problems with thread B. That can't be the right answer.
If you say the one associated with thread B, then that means that during the processing of new orders, control could suddenly be yanked out and sent back to try thread B catch block. But then what happenned to processing new orders? Do we just stop in the middle? Do we not even hit the finally block? And when we're done, do we then just keep executing and fall through to processing new orders again? Do we process orders twice? This can't be the right answer either.
Thus, there is nowhere to go if run throws an exception. The only logical thing to do is to have the run method catch any exceptions thrown itself, and handle them within the new thread.
throws declarations are part of the methods signature. To allow checked exceptions for Runnable#run, one had to declare them on the Runnable interface and had to try/catch everytime we start a thread.
Then again, we usually don't call the run method, we just implement it. We start() a Thread and then, somehow, the run method is called.
But the most obvious reason: When we start threads, we usually don't want to wait until the run method terminates just to catch exceptions like this:
try {
new Worker().start(); // now wait until run has finished
} catch (SomeThreadException oops) {
// handle checked exception
}
The reason is that exception is thrown back to the caller. Caller of run() method is not your code. It is the Thred itself. So even if run() throws exception the program cannot catch it.
You should put thread execution result to some class level variable and then read it from there. Or alternatively use new API: executors and interface Callable that declares method call() that returns future result of the thread execution.
The more obvious solution to the previous answers is that if you throw a checked exception, you are not correctly implementing run() as specified in the runnable interface.
It won't even compile:
run() in TestClass cannot implement run() in java.lang.Runnable;
overridden method does not throw java.lang.Exception