zoukankan      html  css  js  c++  java
  • 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;
            }
        }
    }

  • 相关阅读:
    Android TextView中实现点击文本超链接(无下划线)的封装类
    first day for new job
    配置Log4j(非常具体)
    验证数字的正则表达式集
    虚拟化知识点
    Java实现第十届蓝桥杯数的分解
    Java实现第十届蓝桥杯数的分解
    Java实现第十届蓝桥杯数的分解
    Java实现第十届蓝桥杯数列求值
    Java实现第十届蓝桥杯数列求值
  • 原文地址:https://www.cnblogs.com/luojiabao/p/11309007.html
Copyright © 2011-2022 走看看