patricK
patricK

Reputation: 1105

Two threads accessing same variable lock application

The following code was summed up the application, the application randomly was locked in

while (flag)

This code, running on my machine gets caught, in another machine he finished normally

The output generated here is:

INIT
END
before while
before flag
after flag

Code:

package threads;

public class Run implements Runnable {

private Thread thread;
private boolean flag = true;

public void init() {
    thread = new Thread(this);
    thread.setName("MyThread");
    thread.start();
}

@Override
public void run() {
    try {

        int i = 0;
        while (i < 1000) {
            i++;
        }
        System.out.println("before flag");
        flag = false;
        System.out.println("after flag");

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        flag = false;
    }
}

public void end() {
    thread.interrupt();
    thread = null;

    System.out.println("before while");
    while (flag) {
        // try { Thread.sleep(100);} catch (InterruptedException e) {}
    }
    ;
    System.out.println("after while");
}

public static void main(String[] args) {
    Run r = new Run();
    System.out.println("INIT");
    r.init();
    System.out.println("END");
    r.end();
}
}

Why when I change the value of flag the main thread does not pass through loop?

Upvotes: 0

Views: 174

Answers (1)

Radiodef
Radiodef

Reputation: 37855

Change

private boolean flag = true;

to

private volatile boolean flag = true;

Without volatile, there is no guarantee the waiting thread needs to see the value get updated. HotSpot might even inline while(flag) to while(true) if the loop spins enough times.

See Memory Consistency Errors.


Also, what you're doing is called a spinlock. Normally you should use thread.join() instead. A spinlock is wasteful of resources because the waiting thread is actually working (checking a variable) the entire time it is supposed to be waiting.

Upvotes: 1

Related Questions