• Collections.synchronizedList使用方法陷阱(1)


    无意发现了这个例子,拿来记住

    @NotThreadSafe
    class BadListHelper <E> {
        public List<E> list = Collections.synchronizedList(new ArrayList<E>());

        public synchronized boolean putIfAbsent(E x) {
            boolean absent = !list.contains(x);
            if (absent)
                list.add(x);
            return absent;
        }
    }

    虽然说putIfAbsent方法加了synchronized的锁关键字,但是这个putIfAbsent方法获得锁和list对象的获得锁不是同一个锁;

    putIfAbsent获得锁是BadListHelper这个类的锁对象,

    list获得锁对象是list;

    如果这么写,那list依旧能够被其他线程获取锁对象来改变list对象的值,就会导致数据出错,或者两两线程在访问这个方法的时候拿到的list数据可能会有错误;所以这么写是不对的;

    要想保证list数据不出错,就要给他自己上锁,其他线程将不能获得list锁来来改变list对象。

    @ThreadSafe
    class GoodListHelper <E> {
        public List<E> list = Collections.synchronizedList(new ArrayList<E>());
        public boolean putIfAbsent(E x) {
            synchronized (list) {  //获得list锁对象,其他线程将不能获得list锁来来改变list对象。
                boolean absent = !list.contains(x);
                if (absent)
                    list.add(x);
                return absent;
            }
        }
    }

  • 相关阅读:
    Ubuntu中root用户和user用户的相互切换
    Linux扩展权限
    計蒜客/填志愿(匈牙利算法)
    計蒜課/排澇(Edmond-Karp)
    計蒜客/數正方形(dp)
    51nodcontest#24 A(xjb)
    計蒜客/节食的限制(01背包)
    計蒜客/小教官(xjb)
    atcoder#073D(枚舉)
    Educational Codeforces Round 20 C(math)
  • 原文地址:https://www.cnblogs.com/luojiabao/p/11309007.html
Copyright © 2020-2023  润新知