0

I'm trying to start/stop Java threads in the following way.

public class ThreadTester {
    public static void main(String[] args) {
        MyThread mt;
        int max = 3;

        for (int i = 0; i < max; i++) {
            mt = new MyThread();
            mt.start();
            mt.finish();
        }
    }
}

public class MyThread extends Thread {
    private volatile boolean active;

    public void run() {
        this.active = true;
        while (isActive()) {
            System.out.println("do something");
        }
    }

    public void finish() {
        this.active = false;
    }

    public boolean isActive() {
        return active;
    }
}

Everything works as expected only if max <= 2. Otherwise some threads continue with their output, although isActive should return false. That was at least my expectation.

The question: what is the proper way to synchronize a variable between the "master" and it's "slave" threads?

3
  • 1
    It would help to explain why you think it's not working if max > 2 Commented Nov 11, 2010 at 23:22
  • Based on the code max seems to be irrelevant to why its failing. Commented Nov 11, 2010 at 23:24
  • 3
    the number is not irrelevant. depending on the number of cores and thread scheduling, hypothetically you might start up 2 threads, but the third thread gets finish called on it before run() happens Commented Nov 11, 2010 at 23:25

3 Answers 3

8

You should initialize active to true during declaration and NOT in a run method.

public class MyThread extends Thread {
    private volatile boolean active = true;

    public void run() {
        // this.active = true;
        while (isActive()) {
            // do nothing
        }
    }

    public void finish() {
        this.active = false;
    }
}

The way you are doing it there is a race condition.

Also, the better approach for safely stopping a thread is to use interruption.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Alexander, the initialization of active in the constructor did the trick.
2

When you say start you are saying that thread is ready for execution but the run method doesn't start at that moment (it starts when scheduler says). So, it is quite possible that you first do this.active = false and than get stuck in the endless loop.

3 Comments

+1. Very good and to the point explanation of cause and effect.
Thank you, I understand your comment. But my issue is that threads "continue to live" although they shouldn't.
Well that is not an issue because, as I sad, the thread will get stuck in the loop and will continue to live. Alexander Pogrebnyak gave the right solution how to stop this.
0

what isn't working as expected?

i don't see anything in there that's synchronized across threads, aside from your active member, which isn't really shared, as its private... and since the only method that modifies it sets it to false.

The only thing i can see there is that you might be calling finish before your thread ever runs, which is more and more likely to happen as you increase the number of threads.

if you wanted your thread to do at least one thing before stopping, you could switch your while loop to a do instead:

do
{
    // do nothign at least once
}
while( active );

then each thread would do something before checking to see if it should stop.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.