请稍等 ...
×

采纳答案成功!

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

老师好,帮看一下

老师好,请教一下,下面这个类,System.out.println(“进入while循环了”);这句话注释和不注释,执行结果为什么会大不一样呢.我自己没有想明白.望指教一下.

import java.util.ArrayList;

@SuppressWarnings("all")
public class Demo {
    private static ArrayList<String> list = new ArrayList();

    public static void main(String[] args) throws Exception {
        new Thread(new Runnable() {
            boolean flag = true;
            String latestEle = null;

            public void run() {
                System.out.println("myThread1中的run方法开始执行了");

                while (flag) {
/**
   如果注释下面这个打印语句("进入while循环了"),下面的if语句("进入if了")也不会打印
   如果不注释下面这个打印语句("进入while循环了"),下面的if语句("进入if了")会打印
 */
//                    System.out.println("进入while循环了");

                    if (list.size() != 0) {
                        System.out.println("进入if了");
                        latestEle =list.get(list.size() - 1);
                        try {
                            Thread.sleep(1000L);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }

                        System.out.println("获取最后添加的元素是:" + this.latestEle);
                        System.out.println();
                    }
                }

            }
        },"myThread1").start();


        Thread.sleep(8L);
        list.add("aa");
        list.add("bb");
        System.out.println("主线程执行完成-----打印list:" + list);
    }
}

图片描述
图片描述

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

1回答

悟空 2024-06-17 22:59:52

因为System.out.println("进入while循环了")会让子线程感知到 list 内容的变化,从而通过了 if判断,这个涉及可见性的问题

0 回复 有任何疑惑可以回复我~
  • 提问者 慕尼黑8163989 #1
    定义一个变量listSize,加上volatile关键之后,就好了.子线程不会再"卡住了".是不是就是老师说的可见性.我新写了一个Demo2类
    https://blog.csdn.net/shichunyuez/article/details/139781446?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22139781446%22%2C%22source%22%3A%22shichunyuez%22%7D
    回复 有任何疑惑可以回复我~ 2024-06-18 19:17:18
  • 提问者 慕尼黑8163989 #2
    对于原来的Demo类,flag为true,while循环会非常频繁的判断if条件,一开始list.size()是0,if条件不满足,myThread1线程就会缓存list.size()的结果,不会每次都真实的访问list集合真正的size变量主存。main线程修改了size变量值后,本来要同步myThread1线程缓存的size值,但是因为while循环频繁读取缓存值,导致没有机会修改'这个缓存值。但是要是加了打印语句就不一样了,相当于有空隙时间给缓存与主存值同步。
    是不是这么理解的
    回复 有任何疑惑可以回复我~ 2024-06-18 19:19:56
  • 悟空 回复 提问者 慕尼黑8163989 #3
    是对的
    回复 有任何疑惑可以回复我~ 2024-06-19 22:23:43
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信