两个线程访问相同的变量锁应用程序

时间:2015-05-25 18:46:25

标签: java multithreading

以下代码总结了应用程序,应用程序被随机锁定在

  

while(flag)

在我的机器上运行的这段代码被抓住,在另一台机器上他正常完成

此处生成的输出是:

INIT
END
before while
before flag
after flag

代码:

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();
}
}

为什么当我更改标志的值时主线程没有通过循环?

1 个答案:

答案 0 :(得分:1)

更改

private boolean flag = true;

private volatile boolean flag = true;

如果没有volatile,则无法保证等待线程需要查看值更新。如果循环播放足够的时间,HotSpot甚至可以将while(flag)内联到while(true)

请参阅Memory Consistency Errors

此外,您正在做的事情称为spinlock。通常您应该使用thread.join()代替。自旋锁是浪费资源的,因为等待线程实际上正在工作(检查变量)它应该等待的整个时间。