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

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

最新文章

  1. T-SQL编程 —— 用户自定义函数(标量函数)
  2. jquery 无缝滚动 jquery.kxbdmarquee
  3. PHP输出当前进程所有变量 / 常量 / 模块 / 函数 / 类
  4. PHP部分---字符串处理(文中例子不断更新);
  5. 浏览器URL访问网页具体发生了什么
  6. Oracle-11g 从表空间删除数据文件
  7. phpmyadmin安装教程及配置设置
  8. OpenCV——IplImage
  9. vim ctl+v批量添加/删除
  10. Highest Rated Features
  11. windows与linux下的\r\n
  12. javascript函数调用中的方法调用模式
  13. 易出错的bug避免
  14. vue项目中px自动转换为rem
  15. php 多次导入文件导致 Cannot redeclare class
  16. PhpStorm 自定义快捷键
  17. synchronized(this)、synchronized(class)与synchronized(Object)的区别
  18. SAP销售订单屏幕字段控制隐藏,必输等
  19. 浅谈IM软件怎样建立安全socket连接、登录
  20. VB.Command()的参数

热门文章

  1. MySQL(2): 窗口函数\备份与恢复\性能优化\权限管理
  2. ESLint未定义报错
  3. 一个比较全的C++农历算法(转)
  4. ENGG1310 Electricity and electronics P1.2 Electronic Communication
  5. 读取excel等文件根据注解自动装填为实体类
  6. 前端js校验小数点
  7. 【ubuntu20】解压文件
  8. 高效XML绑定框架JIBX
  9. 如何为 Debian 11 安装图形用户界面 (GUI)
  10. 批量获取title