AsPas
AsPas

Reputation: 439

Problem getting threads to terminate and program to end execution

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 hashThreadhashes 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

Answers (2)

Karam Mohamed
Karam Mohamed

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

AsPas
AsPas

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

Related Questions