请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

师兄,关于可见性的问题

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

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






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


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


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


https://img1.sycdn.imooc.com//szimg/5db6508709862ceb04190277.jpg


https://img1.sycdn.imooc.com//szimg/5db6509609c86dd903960212.jpg



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


正在回答 回答被采纳积分+3

3回答

提问者 manong22 2019-10-28 14:47:18
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 15:18:42
悟空 2019-10-28 13:13:08

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

0 回复 有任何疑惑可以回复我~
  • 提问者 manong22 #1
    师兄我代码发了
    回复 有任何疑惑可以回复我~ 2019-10-28 14:47:36
悟空 2019-10-28 11:59:06

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

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号