Reputation: 439
I'm doing a simple program in java.
2 threads should append their id
to a string and the third thread then hashes the whole string. This is supposed to happen 5 times. And it does work, the problem is the program just keeps running and doesn't stop execution. I have tried break
but still it hangs.
I am assuming a deadlock of some sort is happening but I can't understand why or how.
public void run()
{
while(numOfIterations > 0)
{
if (numOfIterations == 0){
break;
}
if(this.id == "A")
{
appendThread(this.id);
}
else if(this.id == "B")
{
appendThread(this.id);
}
else
{
hashThread();
}
try
{
Thread.sleep(interval);
if(this.nextThread.isAlive())
{
nextThread.interrupt();
}
else
{
nextThread.start();
}
Thread.sleep(Long.MAX_VALUE);
}
catch (InterruptedException e)
{
System.out.println("Interrupted Thread : "+ this.iD);
}
}
}
Note: The run
method is inside of a class that extends Thread, which has a property called nextThread
(basically a reference to the thread that is supposed to perform the next task.
thread1 -> thread2 -> thread3 -> thread1 ...).
The methods appendThread()
appends the id to the string and hashThread
hashes the string.
Both methods decrease the numOfIterations
variable by one.
This is the Output:
hashed word = b86fc6b051f63d73de262d4c34e3a0a9
numOfIterations : 4
Interrupted Thread : A
Interrupted Thread : B
Interrupted Thread : C
hashed word = a63e3d9e4d46287e71ec1248d1be5782
numOfIterations : 3
Interrupted Thread : A
Interrupted Thread : B
Interrupted Thread : C
hashed word = 444b8618908e49ca64c8eafab94add38
numOfIterations : 2
Interrupted Thread : A
Interrupted Thread : B
Interrupted Thread : C
hashed word = 535cfc91d9e96b57395000fdae460bf1
numOfIterations : 1
Interrupted Thread : A
Interrupted Thread : B
Interrupted Thread : C
hashed word = 3e9c9cfb98a356ff155fa67abbbaccb9
numOfIterations : 0
Interrupted Thread : A
The output is correct the only problem is the program doesn't end. Also, notice how the output ends with Interrupted Thread : A
but not B or C.
Any help would be greatly appreciated.
Upvotes: 2
Views: 475
Reputation: 871
You have to do it as one of the if-statements inside the try :
if(this.nextThread.isAlive()) {
nextThread.interrupt();
}
else if (numOfIterations == 0){
break;
} else {
nextThread.start();
}
Upvotes: 0
Reputation: 439
After many hours I have figured out what happened. Since each thread is waiting to be interrupted by the previous thread, a deadlock occurred while Thread B and C were waiting for thread A to awake them, but A had already exited the function.
The reason Interrupted Thread : A
gets printed at the end is that Thread A does terminate it's method but Thread B and C are still sleeping.
So I just needed to make thread A interrupt thread B before it exists the function by calling nextThread.interrupt(). This way A awakes B before exiting the method and B awakes C and so all threads can exit the function.
Adding this to the end of the function solved my problem.
if (numOfIterations == 0){
nextThread.interrupt();
}
Upvotes: 1