师兄,关于可见性的问题

来源:12-14 保证可见的规则

manong22

2019-10-28

第一个问题,线程a执行下面第一个代码,线程B执行第二个,只打印a=2这种情况,我可不可以理解为线程A只在第一次读取a变量时从主内存中读,然后保存副本修改,在打印时不会读主内存,所以打印只为2,不会出现3的情况。

http://img1.sycdn.imooc.com/szimg/5db64ed30953005200000000.jpg






http://img1.sycdn.imooc.com/szimg/5db64f060990059704070217.jpg


第二个问题:代码在上面基础上多了一个 b = a的操作,然后打印出了3,2,想了半天出现这个结果只可能是因为在打印时从主内存中读取了a的值,然后就和上面第一个问题矛盾了


http://img1.sycdn.imooc.com/szimg/5db650ed09f320c702870065.jpg


http://img.mukewang.com/szimg/5db6508709862ceb04190277.jpg


http://img.mukewang.com/szimg/5db6509609c86dd903960212.jpg



第三个问题,上面第二个问题的代码还有一个结果打印出1,1的结果,这不就违反了单线程happen-before原则了吗,老师帮忙解释下,最好详细点,我有点晕


写回答

3回答

manong22

提问者

2019-10-28

package src.threadcoreknowledge.jmm;

import java.util.concurrent.CountDownLatch;

/**
 * @program: muti_thread_AND_hign_concurrency
 * @author: yaopeng
 * @create: 2019-10-27 21:18
 **/
public class test {

     static volatile int a =1 ;
    static volatile int b =1 ;

    public static void main(String[] args){


        for(;;){

            a = 1;
            b = 1;

            CountDownLatch latch = new CountDownLatch(1);
          Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {

                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                 a = 2;
                 b = a;
                System.out.println(a+","+ b );
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                a = 3;
            }
        });
            thread1.start();
            thread2.start();
            latch.countDown();


    }
    }
}

师兄代码已经发了



0
1
悟空
问题1:工作内存随时都可能和主内存同步,并不需要显示触发,所以也可能打印出3,只不过这并不一定发生,是有概率的。 ​问题2:见问题1 问题3:你代码里的a和b,不是本地变量(方法里的变量),所以可能是下一次for循环的时候,把a和b修改成1,1,然后thread1开始打印,所以不违反happen-before原则。
2019-10-28
共1条回复

悟空

2019-10-28

我要有你main函数的代码才能分析,贴一下完整代码吧

0
1
manong22
师兄我代码发了
2019-10-28
共1条回复

悟空

2019-10-28

麻烦把代码文字版贴一下,我运行看看。现在的图片不方便复制。

0
0

线程八大核心+Java并发原理及企业级并发解决方案

完整的并发知识网络+丰富的工作内容分享+50余道并发高频面试题

2512 学习 · 939 问题

查看课程