H5W3
当前位置:H5W3 > 其他技术问题 > 正文

问一个线程的问题

下面代码,如果主线程sleep了1秒钟(把main方法的Thread.sleep(1000)注释打开)再操作MyObj对象,为什么子线程的方法没有输出?

public class ThreadTest {

    public static void main(String[] args) throws InterruptedException {
        MyObj mo = new MyObj();
        MyThread t1 = new MyThread(mo, 1);
        t1.start();

        MyThread t2 = new MyThread(mo, 2);
        t2.start();

        // Thread.sleep(1000);
        mo.setCry(true);

        // Thread.sleep(1000);
        mo.setEat(true);
    }

}

class MyObj {
    private boolean eat;
    private boolean cry;

    public boolean isCry() {
        return cry;
    }

    public void setCry(boolean cry) {
        System.out.println("cry------" + cry);
        this.cry = cry;
    }

    public boolean isEat() {
        return eat;
    }

    public void setEat(boolean eat) {
        System.out.println("eat-------" + eat);
        this.eat = eat;
    }

}

class MyThread extends Thread {
    private MyObj mo;
    private int type;

    public MyThread(MyObj mo, int type) {
        this.mo = mo;
        this.type = type;
    }

    @Override
    public void run() {
        while (true) {
            if (type == 1) {
                if (mo.isCry()) {
                    System.out.println("11111");
                    mo.setCry(false);
                }
            } else if (type == 2) {
                if (mo.isEat()) {
                    System.out.println("2222222");
                    mo.setEat(false);
                }
            } else {
                System.out.println("33333333333");
            }
        }
    }
}

没有sleep的结果(有可能顺序不一样,因为多线程):

cry------true
eat-------true
2222222
eat-------false
11111
cry------false

如果sleep了,结果如下:

cry------true
eat-------true

回答:

把这两行

private boolean eat;
private boolean cry;

改成

private volatile boolean eat;
private volatile boolean cry;

就好了,这个跟java的内存模型有关,每个线程有自己的copy,eat跟cry什么时候跟memory里的同步,取决于jvm。加上volatile是如果有更新马上同步。

本文地址:H5W3 » 问一个线程的问题

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址