static 的num的数值增加了1000,同时也减少了1000,之后还sleep了1秒,在这1面只能num的数值已经处理完,所以最终输出还是0

解决方案 »

  1.   

    这么写:
    public class Main {
     
     
        public static volatile int num = 0;
         
        public static void main(String [] args){
            Thread thread = new Thread(){
                @Override
                public void run() {
                    int i = 10000;
                    while(i-- > 0){
                        num++;
                    }
                };
            };
            Thread thread2 = new Thread(){
                @Override
                public void run() {
                    int i = 10000;
                    while(i-- > 0){
                        num--;
                    }
                }
            };
            thread.start();
            thread2.start();
            try {
                Thread.sleep(1000);    //等待线程执行
            } catch (InterruptedException e) {
            }
            System.out.println("Final: " + num);
        }
    }
    因为你的程序中两个线程各自操作缓存中的变量,最后才刷回主存,所以永远是0.
    可以了解下java内存模型,指令重排序,网上资料不少。
      

  2.   

    为何我输出的都是随机的?
    Final: 604
    Final: 268
    Final: 394
      

  3.   

    先由两个线程操作,那么两个线程的结果应该是:一个为10000,另一个为-10000。那么刷回主存应该是这两个值当中的一个吧?
    我又试着跑了下我的代码,发现各种结果都有可能:10000,-10000,0甚至是乱码。所以我觉得应该是JAVA内存模型有好几种执行方案分别起了作用?(确实对内存模型不是很懂,正在看...)
    结论就是一定要对共享的数据做同步。
    谢谢你的答案!
      

  4.   

    先由两个线程操作,那么两个线程的结果应该是:一个为10000,另一个为-10000。那么刷回主存应该是这两个值当中的一个吧?
    我又试着跑了下我的代码,发现各种结果都有可能:10000,-10000,0甚至是乱码。所以我觉得应该是JAVA内存模型有好几种执行方案分别起了作用?(确实对内存模型不是很懂,正在看...)
    结论就是一定要对共享的数据做同步。
    谢谢你的答案!粗略看了一下,我的解释的确有问题,线程调度机制太复杂,我也不明白。总之我们知道如何肯定能产生正确的结果就行了,对于可能出现的错误,有时候经过精心的构造也未必能出现。