代码如下,正常应该两秒后打印出break,但是为什么程序会死循环呢,但是如果在while里面加上个sleep又可以得到预期结果了,很困惑,望各位帮忙解答package test;import java.util.ArrayList;
import java.util.List;public class ThreadTest { public void test(){
List<String> list = new ArrayList<String>();
list.add("false");
test ab = new test(list);
ab.start();
while(true){
if(list.get(0).equals("true")){
System.out.println("break!");
break;
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
ThreadTest a = new ThreadTest();
a.test();
}

public class test extends Thread{
List<String> list = null;
public test(List<String> list){
this.list=list;
}
@Override
public void run() {
// TODO 自动生成的方法存根
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
list.set(0, "true");
}

}}

解决方案 »

  1.   

    你两个类操作的不是同一个list,你可以把list放在ThreadTest 中,这样就整个类可见了。
      

  2.   

    在test线程中拿到的list 是一个test() 中list的内存拷贝,test线程执行完并修改了值之后 就看什么时候把这个改变的值压入 主内存中 然后在等cpu什么时候才会再次将test线程更新后的list刷新到test()方法的list本地内存中
    test()--list内存数据 ------->  主内存list------复制给--> test()线程list  -----list值改变后----> 主内存----刷新到----> test() 的list内存。
    至于您说的那个在while 处加 sleep操作 应该也是便于 cpu写入最新的住内存list到test()方法中
    个人认为要把list提到 threadtest类成员 并添加volatile 使其内存对每个线程可见
    回答如有不妥 请回复拍砖
      

  3.   

    楼主的代码,无论加不加sleep都不会死在那里。楼主是不是代码贴错了呢?关于2楼,你看一下代码里总共new 了几个list呢?
      

  4.   

    这应该是多线程cpu使用权分配的不确定性吧,2秒后虽然新创建的线程可以执行,但是可能因为没有抢占到cpu的资源,所以值没有被置为true,所以主线程一直不断的执行下去,当在主线程中增加sleep后,新创建的线程就可以得到cpu的资源,然后直接把值设为true,主线程sleep结束后自然可以终止循环了,其中list是共享资源,对共享资源的一般要同步,避免发生不期望错误,你把sleep(2000)和list.set(0, "true");放在同步代码块中应该就可以了