I'm trying to work on the famous dining philosophers and its quite finished but I'm having a quite hard time trying to interrupt threads.
so as you know in this problem we have 5 threads (philosophers) and the user set an experiment time at which the experiment will end.
worth noticing that I looked multiple answers on StackOverflow.
The first one is from @Konrad Reiche How do you kill a Thread in Java? /Stackoverflow link
In that particular post, people have stated that using volatile boolean as a flag might work out but I'm afraid that it is stated in the exercise paper that I cant use the volatile boolean to interrupt a thread but I can use it for other purposes. (studying exercise).
The second one is Thread interrupt() does not interrupt thread/Stackoverflow link
yet nothing really helped!.
I will try to provide the necessary code and I hope someone would just point out my mistake/s. the class Philosopher is public and extends Thread!.
when using volatile boolean like this it works:
private volatile boolean isNotStopped=true;
@Override
public void stopPhilosopher() {
System.out.printf("\n%s will stop.\n",selfPhilosopher.getName());
selfPhilosopher.interrupt();
isNotStopped=false;
}
@Override
public void run() {
while (isNotStopped){//selfPhilosopher is a thread equals to this!.
try {
think();
eat();
} catch (InterruptedException e) {//somehow this was never triggered!.
System.out.printf("%s was interrupted.\n",selfPhilosopher.getName());
}finally {//in the finally block i always get RUNNER, FALSE
System.out.printf("the %s is %s and is interrupted %b.\n", selfPhilosopher.getName(),selfPhilosopher.getState(), selfPhilosopher.isInterrupted());
}
}
}
replacing selfPhilosopher.isInterrupted()
with Thread.currentThread().isInterrupted()
didn't make any difference as selfPhilosopher=this;
yet I was getting "will stop" from the stopPhilosopher()
method but the threads seem to be like zombies keep coming back to life :(
due to the fact that I'm pretty convinced by the opinion of @Konrad Reiche from the first reference provided and the answer of @Nathan Hughes I will stick with using the boolean flag provided by the java isInterrupted()
instead of using a volatile flag.
@Override
public void stopPhilosopher() {
System.out.printf("\n%s will stop.\n",selfPhilosopher.getName());
selfPhilosopher.interrupt();
}
@Override
public void run() {
while (!selfPhilosopher.isInterrupted()){//selfPhilosopher is a thread equals to this!.
try {
think();
eat();
} catch (InterruptedException e) {//somehow this was never triggered!.Now it works.
System.out.printf("%s was interrupted from catch clause!..\n",selfPhilosopher.getName());
selfPhilosopher.interrupt();
}
}
}
OUTPUT:
Philosopher2 in seat nr: 2 was interrupted from catch clause!..
When an InterruptedException is thrown, the interrupt flag is cleared. That means the next check your loop makes will indicate the thread is not interrupted and the thread will keep on running. That's what you're seeing when your finally block prints out false for the interrupt flag.
This is described in the API doc for the sleep method:
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Add this line to the block where you catch an InterruptedException:
Thread.currentThread().interrupt(); // restores interrupt flag