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

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

Collections.synchronizedList使用方法陷阱(1)的更多相关文章

  1. Collections.synchronizedList线程安全性陷阱

    摘要: 详细的解析:Collections.synchronizedList 1 :关注要点,为什么在有synchroniezed方法的同时会出现 Collections.synchronizedLi ...

  2. 【集合类型的并发】Collections.synchronizedList

    摘要: 详细的解析:Collections.synchronizedList :关注要点,为什么在有synchroniezed方法的同时会出现 Collections.synchronizedList ...

  3. Collections.synchronizedList使用

    1.SynchronizedList类具体代码: static class SynchronizedList<E> extends SynchronizedCollection<E& ...

  4. CopyOnWriteArrayList与Collections.synchronizedList的性能对比

    列表实现有ArrayList.Vector.CopyOnWriteArrayList.Collections.synchronizedList(list)四种方式. 1 ArrayList Array ...

  5. CopyOnWriteArrayList与Collections.synchronizedList的性能对比(转)

    列表实现有ArrayList.Vector.CopyOnWriteArrayList.Collections.synchronizedList(list)四种方式. 1 ArrayList Array ...

  6. CopyOnWriteArrayList&Collections.synchronizedList()

    1.ArrayList ArrayList是非线性安全,此类的 iterator() 和 listIterator() 方法返回的迭代器是快速失败的:在创建迭代器之后,除非通过迭代器自身的 remov ...

  7. Collections.synchronizedList 、CopyOnWriteArrayList、Vector介绍、源码浅析与性能对比

    ## ArrayList线程安全问题 众所周知,`ArrayList`不是线程安全的,在并发场景使用`ArrayList`可能会导致add内容为null,迭代时并发修改list内容抛`Concurre ...

  8. 线程安全Collections.synchronizedList

    ollections.synchronizedList引发的线程安全问题 有些容器是线程安全的(Vector,ConcurrentLinkedQueue等),有些则不是(list等),利用类 似 pr ...

  9. ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 以及 同步的集合类 Hashtable 和 Vector Collections.synchronizedMap 和 Collections.synchronizedList 区别缺点

    ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含 ...

  10. 关于Collections.sort()排序方法的源码探索

    /**下面在自己代码中使用Collections.sort()方法去比较Student对象,通过在自己写的类里面通过匿名内部类实现Comparator接口,这个接口是让你自己实现比较器的规则*/ // ...

随机推荐

  1. 浅谈flume

    flume做日志收集的工具,将数据源导入到指定目标中.flume之间可以相互连接组件    source:如何从数据源中取数据,可以认为是两种主动source(主动取数据)和被动source(推给so ...

  2. Git下载、安装与配置

    1.Git下载:   访问Git官网,下载对应操作系统的的安装包.   这里笔者是64位机器,选择如下: 2.Git安装:   打开安装包进行安装:   一路next到Finish:   在CMD中输 ...

  3. 【Linux】常用

    查看端口占用 yum install lsof lsof -i:8080:查看8080端口占用 lsof abc.txt:显示开启文件abc.txt的进程 lsof -c abc:显示abc进程现在打 ...

  4. Fuxploider-20210104

    Usage: fuxploider.py [-h] [-d postData] [--proxy proxyUrl] [--proxy-creds [credentials]] [-f integer ...

  5. 物联网IOT定位技术详解

    早在15世纪,当人类开始探索海洋的时候,定位技术也随之催生.当时的定位方法十分粗糙,就是是运用航海图和星象图以确定自己的位置. 随着社会的进步和科技的发展,定位技术在技术手段.定位精度.可用性等方面均 ...

  6. Jmeter面试

    jmeter面试题及答案 1.解释什么是jmeter? jmeter是一款java开源工具,用于性能负载测试.它旨在分析和衡量web应用程序和各种服务的性能和负载功能行为. 2.说明jmeter的工作 ...

  7. uni-app学习笔记之----页面跳转

    1.声明式跳转 <navigator url="/pages/detail/detail"> <button>跳转至详情页</button> & ...

  8. go - 泛型

    为什么要用泛型 在 go 1.18 前的版本中,如果对传入参数的值不确定时,就要使用空接口的方法传参,然后通过对参数进行断言的方式,取出原结构体. 对泛型切片进行遍历 func printSlice[ ...

  9. D3简介

    (一)D3简介 一.D3是什么 一张图片价值相当于一千个字 D3的全称是 Data-Driven Documents,直译为:数据驱动的文档 D3是一个javaScript的函数库,是用来做数据可视化 ...

  10. a菜单点击标红,其他标黑代码

    <script> let aList = document.querySelectorAll('a'); console.log(aList); for (let index = 0; i ...