目录

  • `synchronizedMap`
    • `synchronizedMap` 概述
    • `synchronizedMap` 的获取示例
    • `synchronizedMap` 源码解读
      • 类的基本属性
      • 构造函数
      • 常见的 `API` 方法
    • `synchronizedMap` ,`Hashtable` 与 `ConcurrentHashMap`
      • 相同点
      • 不同点
  • `synchronizedList`
    • `synchronizedList` 概述
    • `synchronizedList` 的获取示例
    • `synchronizedList` 源码解读
      • `synchronizedList` 构造函数
      • 常见的 `API` 方法
    • `synchronizedList`,`Vector` 与 `CopyOnWriteArrayList`
      • 相同点
      • 不同点
  • `synchronizedSet`
    • `synchronizedSet` 概述
    • `synchronizedSet` 的获取示例
    • `synchronizedSet` 源码解读
      • `synchronizedSet` 构造函数
      • 常见的 `API` 方法
    • `synchronizedSet` 与 `CopyOnWriteArraySet`
      • 相同点
      • 不同点

synchronizedMap

synchronizedMap 概述

  • SynchronizedMap 是集合工具类 Collections 的一个静态内部类
  • SynchronizedMap 实现了 Map 接口,同时实现了接口 Serializable,支持序列化
  • 在多线程的情况下,能够保证线程的安全

synchronizedMap 的获取示例

Map<Integer, String> map = new HashMap<>();
Map<Integer, String> synchronizedMap = Collections.synchronizedMap(map);// Collections 调用的 synchronizedMap 方法如下
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {return new SynchronizedMap<>(m);
}

synchronizedMap 源码解读

类的基本属性

// 被 final 修饰的普通 Map 对象
private final Map<K,V> m;    // 互斥锁对象
final Object mutex;

构造函数

// 不指定锁对象
SynchronizedMap(Map<K,V> m) {// 不指定锁对象时,锁对象就是 SynchronizedMap 本身this.m = Objects.requireNonNull(m);mutex = this;
}// 自定义锁对象
SynchronizedMap(Map<K,V> m, Object mutex) {this.m = m;// 锁对象为传入的 mutexthis.mutex = mutex;
}

常见的 API 方法

public int size() {synchronized (mutex) {return m.size();}
}public boolean isEmpty() {synchronized (mutex) {return m.isEmpty();}
}public V get(Object key) {synchronized (mutex) {return m.get(key);}
}public V put(K key, V value) {synchronized (mutex) {return m.put(key, value);}
}public V remove(Object key) {synchronized (mutex) {return m.remove(key);}
}public void putAll(Map<? extends K, ? extends V> map) {synchronized (mutex) {m.putAll(map);}
}public void clear() {synchronized (mutex) {m.clear();}
}public Set<Map.Entry<K,V>> entrySet() {synchronized (mutex) {if (entrySet==null)entrySet = new SynchronizedSet<>(m.entrySet(), mutex);return entrySet;}
}
  • 可以看到,它的所有方法都是加了 synchronized 互斥锁关键字
  • 此外,synchronizedMap 还重写了 Map 中的一些方法,也都是加了 synchronized 互斥锁关键字

synchronizedMapHashtableConcurrentHashMap

相同点

  • 三者都实现了 Map 接口
  • 在多线程的情况下,都可以保证线程的安全

不同点

  • 底层使用的数据结构:Hashtable 使用了数组 + 链表,ConcurrentHashMap 使用了数组 + 链表 + 红黑树
  • 默认的初始容量:HashTable11ConcurrentHashMap16
  • 保证线程安全的机制:synchronizedMapHashtable 都是为每个方法加了synchronized 互斥锁关键字,ConcurrentHashMap 使用了 Synchronized + CAS + Volatile 机制来保证线程安全
  • 多线程的情况下执行效率:ConcurrentHashMap 要高于 synchronizedMapHashtable

synchronizedList

synchronizedList 概述

  • synchronizedList 是集合工具类 Collections 的一个静态内部类
  • synchronizedList 实现了 List 接口
  • 在多线程的情况下,能够保证线程的安全

synchronizedList 的获取示例

List<Integer> newList = new ArrayList<>();
List<Integer> synchronizedList = Collections.synchronizedList(newList);// Collections 调用 synchronizedList 方法如下
public static <T> List<T> synchronizedList(List<T> list) {return (list instanceof RandomAccess ?new SynchronizedRandomAccessList<>(list) :new SynchronizedList<>(list));
}

synchronizedList 源码解读

synchronizedList 构造函数

SynchronizedList(List<E> list) {super(list);this.list = list;
}// 指定互斥锁对象,并调用父类 SynchronizedCollection 的构造函数
SynchronizedList(List<E> list, Object mutex) {super(list, mutex);this.list = list;
}

常见的 API 方法

public E get(int index) {synchronized (mutex) {return list.get(index);}
}public E set(int index, E element) {synchronized (mutex) {return list.set(index, element);}
}public void add(int index, E element) {synchronized (mutex) {list.add(index, element);}
}public E remove(int index) {synchronized (mutex) {return list.remove(index);}
}public boolean addAll(int index, Collection<? extends E> c) {synchronized (mutex) {return list.addAll(index, c);}
}public ListIterator<E> listIterator() {return list.listIterator();
}public ListIterator<E> listIterator(int index) {return list.listIterator(index);
}@Override
public void replaceAll(UnaryOperator<E> operator) {synchronized (mutex) {list.replaceAll(operator);}
}// 其父类 SynchronizedCollection 的方法
public int size() {synchronized (mutex) {return c.size();}
}public boolean isEmpty() {synchronized (mutex) {return c.isEmpty();}
}public boolean contains(Object o) {synchronized (mutex) {return c.contains(o);}
}@Override
public void forEach(Consumer<? super E> consumer) {synchronized (mutex) {c.forEach(consumer);}
}
......
  • 可以看到添加、删除、修改、查询等操作都通过 synchronized 实现了同步锁来保证这些操作是线程安全的
  • 在迭代器操作是没有添加同步锁的,因此使用迭代器进行操作使会出现线程不安全的情况,但我们也可以手动添加同步锁来实现迭代的时候线程安全

synchronizedListVectorCopyOnWriteArrayList

相同点

  • 三者都是线程安全的 List

不同点

  • 扩容机制:Vector 每次扩容的大小都是原来数组大小的 2 倍,而 CopyOnWriteArrayList 不需要扩容,通过 COW 思想就能使数组容量满足要求
  • 保证线程安全机制:synchronizedListVector 的每个方法都进行了加锁,而 CopyOnWriteArrayList 的读操作是不加锁的,因此 CopyOnWriteArrayList 的读性能远高于 synchronizedListVector
  • 在多线程的读多写少的情况下执行效率:CopyOnWriteArrayList 要高于 synchronizedListVector

synchronizedSet

synchronizedSet 概述

  • synchronizedSet 是集合工具类 Collections 的一个静态内部类
  • synchronizedSet 实现了 Set 接口
  • 在多线程的情况下,能够保证线程的安全

synchronizedSet 的获取示例

Set<String> set = new HashSet<>();
Set<String> synchronizedSet = Collections.synchronizedSet(set);// Collections 调用 synchronizedSet 方法如下
public static <T> Set<T> synchronizedSet(Set<T> s) {return new SynchronizedSet<>(s);
}

synchronizedSet 源码解读

synchronizedSet 构造函数

SynchronizedSet(Set<E> s) {super(s);
}// 指定互斥锁对象,并调用父类 SynchronizedCollection 的构造函数
SynchronizedSet(Set<E> s, Object mutex) {super(s, mutex);
}

常见的 API 方法

=在 synchronizedSet 中只有 equals()hashCode() 方法,所以我们看其父类 SynchronizedCollection的方法

public int size() {synchronized (mutex) {return c.size();}
}public boolean isEmpty() {synchronized (mutex) {return c.isEmpty();}
}public boolean contains(Object o) {synchronized (mutex) {return c.contains(o);}
}public Iterator<E> iterator() {return c.iterator();
}public boolean add(E e) {synchronized (mutex) {return c.add(e);}
}public boolean remove(Object o) {synchronized (mutex) {return c.remove(o);}
}public boolean addAll(Collection<? extends E> coll) {synchronized (mutex) {return c.addAll(coll);}
}public boolean removeAll(Collection<?> coll) {synchronized (mutex) {return c.removeAll(coll);}
}@Override
public void forEach(Consumer<? super E> consumer) {synchronized (mutex) {c.forEach(consumer);}
}@Override
public Stream<E> stream() {return c.stream();
}
  • 可以看到添加、删除等操作都通过 synchronized 实现了同步锁来保证这些操作是线程安全的
  • 在迭代器操作是没有添加同步锁的,因此使用迭代器进行操作使会出现线程不安全的情况,但我们也可以手动添加同步锁来实现迭代的时候线程安全

synchronizedSetCopyOnWriteArraySet

相同点

  • 二者都是线程安全的 Set

不同点

  • 实现机制:CopyOnWriteArraySet 是通过 CopyOnWriteArrayList 实现的。而CopyOnWriteArrayList 本质是个动态数组,所以 CopyOnWriteArraySet 相当于通过动态数组实现的 Set,而 synchronizedSet 的实现依据于如何创建 synchronizedSet 的实例
  • 保证线程安全的机制:CopyOnWriteArraySet 通过 volatileReentrantLock 来实现的,而 synchronizedSet 是通过给添加、删除等方法添加 synchronized 同步锁来保证的
  • 在多线程的读多写少的情况下执行效率:CopyOnWriteArraySet 要高于 synchronizedSet

synchronizedMap,synchronizedList与synchronizedSet相关推荐

  1. java.util.concurrent介绍

    为什么80%的码农都做不了架构师?>>>    java.util.concurrent 包含许多线程安全.测试良好.高性能的并发构建块.不客气地说,创建 java.util.con ...

  2. java.util.concurrent介绍【转】

    java.util.concurrent介绍 java.util.concurrent 包含许多线程安全.测试良好.高性能的并发构建块.不客气地说,创建 java.util.concurrent 的目 ...

  3. java对象不会被改变_Java 并发编程(二)对象的不变性和安全的公布对象

    二.安全公布 到眼下为止,我们重点讨论的是怎样确保对象不被公布,比如让对象封闭在线程或还有一个对象的内部.当然,在某些情况下我们希望在多个线程间共享对象,此时必须确保安全地进行共享.然而,假设仅仅是像 ...

  4. java并发编程实战阅读总结(a)

    1.锁(lock)与volatile (1).隐式锁,java提供了强制原子性的内置锁机制:synchronized块或synchronized方法. 操作共享状态的复合操作必须是原子的,以避免竞态条 ...

  5. java 共享软件 保护_【Java并发.3】对象的共享

    本章将介绍如何共享和发布对象,从而使他们能够安全地由多个线程同时访问.这两章合在一起就形成了构建线程安全类以及通过java.util.concurrent 类库来构建开发并发应用程序的重要基础. 3. ...

  6. JAVA并发编程实践笔记

    2019独角兽企业重金招聘Python工程师标准>>> JAVA并发编程实践笔记 博客分类: java JAVA并发编程实践笔记 1, 保证线程安全的三种方法:     a, 不要跨 ...

  7. java10 WeakHashMap

    WeakHashMap: 对象所占用的区域是不能直接操作的,都是通过引用来操作.引用分类: 1.强引用(StrongReference):gc(垃圾回收机制)运行时不回收.例如字符串常量池.字符串虽然 ...

  8. Java基础——Day23——Lock和TCP传输

    Day 23 一.Lock 1.1 定义 Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作. 锁是控制多个线程对共享资源进行访问的工具. 通常,锁提供了对共享资 ...

  9. Java 面试(一) | Java基础部分

    文章目录 Java面试基础部分 1.JDK和JRE的区别 2.==和equals的区别 3.两个对象equals比较为true,但却可以有不同的hashcode,对吗? 4.String类相关 5.& ...

  10. 2021-Java面试题(03-29已更新)

    前言 从2021-02-18日开始,收集面试题,坚持更新,加油!!! 面试题 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供了 ...

最新文章

  1. HH的项链 (求区间内有多少个不同的数字)
  2. mysql 命令行访问_Mysql 命令行模式访问操作mysql数据库操作
  3. Oracle 基础篇 --- 表空间的操作
  4. ExecutorService对象的shutdown()和shutdownNow()的区别
  5. 斯坦福大学的机器学习跟深度学习。
  6. SharePoint 2010 - 如何导入\导出WebPart
  7. 洛谷 P1506 拯救oibh总部-dfs染色法
  8. [超简单]C++如何使用MySQL数据库
  9. 10余万行C代码开源之后,我被震惊了。。。
  10. 前端工具lighthouse
  11. CCF201712-3 Crontab(100分)【模拟+文本处理】
  12. Android Studio 修改项目包名(Xposed)
  13. 单细胞----关于Seurat的一些知识
  14. HCIE Security 双机热备 备考笔记(幕布)
  15. Windows常用快捷键和Windows CMD命令大全
  16. 推特自动发帖,快速提升人气
  17. 你不喜欢的工作,就不能把它做好了吗?
  18. 卷积神经网络感受野的计算
  19. 计算圆周率可以根据公式如下:请利用Python提供的itertools模块,我们来计算这个序列的前N项和——python
  20. JGG论坛:赵方庆研究员解析肠道菌群与人体健康(11月10日10:00)

热门文章

  1. 基于鸢尾花卉数据集的Fisher分类器设计
  2. Redraiment的走法
  3. tg3269c网卡驱动linux,TP-Link TG-3269C驱动
  4. matlab算薄板模态,基于MATLAB计算FGM薄板刚柔耦合动力学响应的仿真方法与流程
  5. lua学习 第一章语言要点
  6. 【机器学习系列】GMM第一讲:两个角度认识高斯混合模型
  7. 【ML小结11】高斯混合模型GMM
  8. DNS服务双解析邮箱地址
  9. 如何完成一个深度学习的模型
  10. 实现一个定时任务管理器