synchronizedMap,synchronizedList与synchronizedSet
目录
- `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
互斥锁关键字
synchronizedMap
,Hashtable
与 ConcurrentHashMap
相同点
- 三者都实现了
Map
接口 - 在多线程的情况下,都可以保证线程的安全
不同点
- 底层使用的数据结构:
Hashtable
使用了数组 + 链表,ConcurrentHashMap
使用了数组 + 链表 + 红黑树 - 默认的初始容量:
HashTable
是11
,ConcurrentHashMap
是16
- 保证线程安全的机制:
synchronizedMap
和Hashtable
都是为每个方法加了synchronized
互斥锁关键字,ConcurrentHashMap
使用了Synchronized + CAS + Volatile
机制来保证线程安全 - 多线程的情况下执行效率:
ConcurrentHashMap
要高于synchronizedMap
和Hashtable
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
实现了同步锁来保证这些操作是线程安全的 - 在迭代器操作是没有添加同步锁的,因此使用迭代器进行操作使会出现线程不安全的情况,但我们也可以手动添加同步锁来实现迭代的时候线程安全
synchronizedList
,Vector
与 CopyOnWriteArrayList
相同点
- 三者都是线程安全的
List
不同点
- 扩容机制:
Vector
每次扩容的大小都是原来数组大小的2
倍,而CopyOnWriteArrayList
不需要扩容,通过COW
思想就能使数组容量满足要求 - 保证线程安全机制:
synchronizedList
和Vector
的每个方法都进行了加锁,而CopyOnWriteArrayList
的读操作是不加锁的,因此CopyOnWriteArrayList
的读性能远高于synchronizedList
和Vector
- 在多线程的读多写少的情况下执行效率:
CopyOnWriteArrayList
要高于synchronizedList
和Vector
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
实现了同步锁来保证这些操作是线程安全的 - 在迭代器操作是没有添加同步锁的,因此使用迭代器进行操作使会出现线程不安全的情况,但我们也可以手动添加同步锁来实现迭代的时候线程安全
synchronizedSet
与 CopyOnWriteArraySet
相同点
- 二者都是线程安全的
Set
不同点
- 实现机制:
CopyOnWriteArraySet
是通过CopyOnWriteArrayList
实现的。而CopyOnWriteArrayList
本质是个动态数组,所以CopyOnWriteArraySet
相当于通过动态数组实现的Set
,而synchronizedSet
的实现依据于如何创建synchronizedSet
的实例 - 保证线程安全的机制:
CopyOnWriteArraySet
通过volatile
和ReentrantLock
来实现的,而synchronizedSet
是通过给添加、删除等方法添加synchronized
同步锁来保证的 - 在多线程的读多写少的情况下执行效率:
CopyOnWriteArraySet
要高于synchronizedSet
synchronizedMap,synchronizedList与synchronizedSet相关推荐
- java.util.concurrent介绍
为什么80%的码农都做不了架构师?>>> java.util.concurrent 包含许多线程安全.测试良好.高性能的并发构建块.不客气地说,创建 java.util.con ...
- java.util.concurrent介绍【转】
java.util.concurrent介绍 java.util.concurrent 包含许多线程安全.测试良好.高性能的并发构建块.不客气地说,创建 java.util.concurrent 的目 ...
- java对象不会被改变_Java 并发编程(二)对象的不变性和安全的公布对象
二.安全公布 到眼下为止,我们重点讨论的是怎样确保对象不被公布,比如让对象封闭在线程或还有一个对象的内部.当然,在某些情况下我们希望在多个线程间共享对象,此时必须确保安全地进行共享.然而,假设仅仅是像 ...
- java并发编程实战阅读总结(a)
1.锁(lock)与volatile (1).隐式锁,java提供了强制原子性的内置锁机制:synchronized块或synchronized方法. 操作共享状态的复合操作必须是原子的,以避免竞态条 ...
- java 共享软件 保护_【Java并发.3】对象的共享
本章将介绍如何共享和发布对象,从而使他们能够安全地由多个线程同时访问.这两章合在一起就形成了构建线程安全类以及通过java.util.concurrent 类库来构建开发并发应用程序的重要基础. 3. ...
- JAVA并发编程实践笔记
2019独角兽企业重金招聘Python工程师标准>>> JAVA并发编程实践笔记 博客分类: java JAVA并发编程实践笔记 1, 保证线程安全的三种方法: a, 不要跨 ...
- java10 WeakHashMap
WeakHashMap: 对象所占用的区域是不能直接操作的,都是通过引用来操作.引用分类: 1.强引用(StrongReference):gc(垃圾回收机制)运行时不回收.例如字符串常量池.字符串虽然 ...
- Java基础——Day23——Lock和TCP传输
Day 23 一.Lock 1.1 定义 Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作. 锁是控制多个线程对共享资源进行访问的工具. 通常,锁提供了对共享资 ...
- Java 面试(一) | Java基础部分
文章目录 Java面试基础部分 1.JDK和JRE的区别 2.==和equals的区别 3.两个对象equals比较为true,但却可以有不同的hashcode,对吗? 4.String类相关 5.& ...
- 2021-Java面试题(03-29已更新)
前言 从2021-02-18日开始,收集面试题,坚持更新,加油!!! 面试题 JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供了 ...
最新文章
- HH的项链 (求区间内有多少个不同的数字)
- mysql 命令行访问_Mysql 命令行模式访问操作mysql数据库操作
- Oracle 基础篇 --- 表空间的操作
- ExecutorService对象的shutdown()和shutdownNow()的区别
- 斯坦福大学的机器学习跟深度学习。
- SharePoint 2010 - 如何导入\导出WebPart
- 洛谷 P1506 拯救oibh总部-dfs染色法
- [超简单]C++如何使用MySQL数据库
- 10余万行C代码开源之后,我被震惊了。。。
- 前端工具lighthouse
- CCF201712-3 Crontab(100分)【模拟+文本处理】
- Android Studio 修改项目包名(Xposed)
- 单细胞----关于Seurat的一些知识
- HCIE Security 双机热备 备考笔记(幕布)
- Windows常用快捷键和Windows CMD命令大全
- 推特自动发帖,快速提升人气
- 你不喜欢的工作,就不能把它做好了吗?
- 卷积神经网络感受野的计算
- 计算圆周率可以根据公式如下:请利用Python提供的itertools模块,我们来计算这个序列的前N项和——python
- JGG论坛:赵方庆研究员解析肠道菌群与人体健康(11月10日10:00)