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;
            }
        }
    }

  • 相关阅读:
    HTML <input> 标签
    HTML5 <input> type 属性
    静态页面与动态页面
    string::size_type 页73 size_t 页90
    template method(模板方法)
    C++中创建对象的时候加括号和不加括号的区别(转)
    _declspec(dllexport)和.def(转)
    智能指针
    C++中的delete加深认识
    工厂方法(整理自李建忠<C++设计模式>视频)
  • 原文地址:https://www.cnblogs.com/luojiabao/p/11309007.html
Copyright © 2011-2022 走看看