Reputation: 91
I've got 5 threads; main (represents bank) and 4 other custom threads (client) that I've created. Each of the custom threads has about 6 instructions in it's run method and these instructions execute a method on a shared resource/monitor. I'll post the relevant codes to keep it short and simple. What I want to do is display a message once all threads have finished executing. One of the threads is vulnerable to deadlock in my situation and to overcome it, i force the main thread to sleep a certain amount of time to give all the threads a chance to finish their execution and once the main thread has woken up, it checks if the other threads are alive.. if yes then throw an exception using the .interrupt()
method. Now what I expected to happen was that the thread that catches the interruption to go in a terminated
state but weirdly it doesn't and still maintains its running state. And what I've noticed is that it continues executing the statements in its run method but after the statement that made it go into the wait
state.
In the main thread I check if clientB thread is alive, if yes, throw an exception.
if(clientB.isAlive()){
clientB .interrupt();
}
ClientB's run method is a simple basic run method that calls methods from a monitor.
@Override
public void run() {
System.out.println(threadName + " is in ThreadGroup: " + threadGroupName);
threadState = Student.currentThread().getState().name();
System.out.println("State of studentThread: " + threadState);
Random rnd = new Random();
try {
Code number 1
{...}
Code number 2
{...}
Code number 3
{...}
Code number 4
{...}
Code number 5
{...}
System.out.println("ClientB Terminating");
} catch (InterruptedException ex) {
ex.printStackTrace();
System.out.println("ClientB got interuppted.");
return;
}
}
As you can see, I haven't got any while loops or anything in ClientB's run method. And this is the monitor method that ClientB calls:
@Override
public synchronized void withdrawal(Transaction t) {
while (t.getAmount() > this.balance) {
try {
wait();
} catch (InterruptedException ex) {
System.out.println("Withdrawal method interuppted.");
return;
}
}
{...}
notifyAll();
}
Now when I give main method 10 seconds for all the threads to complete their actions, all the other threads seem to finish within that time apart from ClientB on Code 2 of its method and after calling interrupted, I expect the thread to catch that exception and get killed but what I've noticed is that the Withdrawal method interrupted.
is printed out on the console but not ClientB got interrupted.
and it then goes to finish executing code 3,4,5 and then prints out ClientB Terminating
and stops.. why is this?
Upvotes: 1
Views: 76
Reputation: 9651
When the exception is catched in withdrawal
, it exits the method with a return, so the processing of the exception ends there.
UPDATE:
if you want to continue the processing of the InterruptedException
outside of the withdrawal
method, you can do this:
@Override
public synchronized void withdrawal(Transaction t) throws InterruptedException {
while (t.getAmount() > this.balance) {
wait();
}
{...}
notifyAll();
}
Upvotes: 2
Reputation: 426
To catch the same exception in several places, it should be rethrown, for example:
@Override
public synchronized void withdrawal(Transaction t) throws InterruptedException {
while (t.getAmount() > this.balance) {
try {
wait();
} catch (InterruptedException ex) {
System.out.println("Withdrawal method interuppted.");
throw ex;
}
}
{...}
notifyAll();
}
Upvotes: 1
Reputation: 364
Yes, Maurice is right. You do not pass your exception to the calling method.
You should replace return with throw new InterruptedException(ex.getMessage());
Also if you do not use the try catch in the withdrawal method, it will also do what you intend it to do.
Upvotes: 1