generally2008 2020-04-14 16:55 采纳率: 0%
浏览 376

java ArrayList 的size值在多线程中可见性问题

ArrayList

hello! 想问下大家一个可见性的问题,如果使用ArrayList,开启两个线程,一个线程往这个集合中添加数据,另一个线程中取这个集合的size值,为什么线程中取到的值一直取不到最新的值?

public void testVisibility3() {
        List<Object> list = new ArrayList<>();
        System.out.println("current list size:" + list.size());
        new Thread(() -> {
            System.out.println("thread 1 add ....");
            for (int i = 0; i < 10; i++) {
                list.add("index" + i);
                System.out.println("thread 1 add success size:" + list.size());
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("thread 1 add success");
        }).start();

        new Thread(() -> {
            System.out.println("thread 2 start =======");
            while (list.size() < 5) {
                // 这里不能使用System.out.println方法来进行测试,因为该方法是线程安全的,有同步标识,这样会导致list数据重新从主内存中加载一份
                //                System.out.print("thread 2 read size:" + this.list.size() + "\n");
            }
            System.out.println();
            System.out.println("thread 2 end =======");
        }).start();
    }

如果用main方法启动调用上面的方法,第二个线程一直不能结束,取不到最新的size值;

但如果定义一个对象,对象中有int值

public class Person implements Serializable {


    /** 年齡 */
    private int    age;


    /**
     * 空构造函数
     */
    public Person() {
        //
    }



    public void incrAge() {
        this.age++;
    }

    /**
     * Getter method for property <tt>age</tt>.
     *
     * @return property value of age
     */
    public int getAge() {
        return this.age;
    }

    /**
     * Setter method for property <tt>age</tt>.
     *
     * @param age
     *            value to be assigned to property age
     */
    public void setAge(int age) {
        this.age = age;
    }


    }

但是,我如果使用上面的对象,我对象中有个int值,如果我开启两个线程,一个线程对这个对象的int值赋值,另一个线程从这个对象中取这个int值,int值没有加其它的修饰符,只有个private; 但是取值的这个线程值不然等很久,就能获取到另一个线程赋的值

public void testVisibility4() {

        Person person = new Person();

        new Thread(() -> {
            System.out.println("thread 1 start ======= age =" + person.getAge());
            while (person.getAge() != 12) {
            }
            System.out.println("thred 1 age =======" + person.getAge());
            System.out.println("thread 1 end =======");
        }).start();

        new Thread(() -> {
            System.out.println("thread 2 modify ....");

            for (int i = 0; i < 12; i++) {

                person.incrAge();
            }
            System.out.println("thread 2 modify success");
        }).start();

    }

上面方法运行的结果,一般都会是:

thread 1 start ======= age =0
thread 2 modify ....
thread 2 modify success
thred 1 age =======12
thread 1 end =======

请问下,这个ArrayList在多线程中这个size和一个对象的int值在多线程中它们到底是如何处理的?可见性为什么会不一样了?

  • 写回答

1条回答

  • 毕小宝 博客专家认证 2020-04-15 13:27
    关注

    建议去了解一下 Java 的内存模型,那个知识点会详细解释内存可见性问题。

    评论

报告相同问题?

悬赏问题

  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘