Java中线程安全的集合
Posted XeonYu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中线程安全的集合相关的知识,希望对你有一定的参考价值。
上一篇:
JUC中的常用辅助类(CountDownLatch、CyclicBarrier、Semaphore)
在之前的文章中,我们已经解释过线程安全的概念了。
我们之前大多是通过加锁的方式去解决集合的线程安全问题,也用了一下线程安全的Vector。
除了Vector,还有一些其他的方法来使用线程安全的集合。
通过Collections类获取线程安全的集合
比如,通过 java.util 包下面的 Collections 工具类来获取线程安全的集合。
先来看看Collections中都有哪些方法
如图所示,我们可以通过 Collections.synchronizedList 来获取一个线程安全的List。
同样的,Collections也提供了获取线程安全的 map和set。使用方式都是类似的。
我们先来看看synchronizedList的源码
可以看到,很多方法内部都用了synchronized代码块,所以是线程安全的。
其他的synchronizedMap,synchronizedSet 等方法都是类似的原理。
我们来简单用一用:
先来看个普通的ArrayList
public static void main(String[] args)
List<String> strings = new ArrayList<>();
for (int i = 0; i < 20; i++)
int finalI = i;
new Thread(() ->
strings.add(String.valueOf(finalI));
System.out.println("strings = " + strings);
).start();
运行一下:
可以看到,多运行几次,偶尔会出现 java.util.ConcurrentModificationException
并发修改异常,我们在之前的文章中已经看到过了。
我们改成 Collections.synchronizedList(new ArrayList<>()) 试一下。
代码如下:
public static void main(String[] args)
List<String> strings = Collections.synchronizedList(new ArrayList<>());
for (int i = 0; i < 20; i++)
int finalI = i;
new Thread(() ->
strings.add(String.valueOf(finalI));
System.out.println("strings = " + strings);
).start();
运行结果如下:
可以看到,再也不会出现 并发修改异常了。
JUC中线程安全的集合
JUC是专门处理并发的包,那肯定也给我们提供了线程安全的集合类。
如图所示:
常用的比如:
- CopyOnWriteArrayList
- ConcurrentHashMap
- CopyOnWriteArraySet
- ArrayBlockingQueue
等等
我们看下 CopyOnWriteArrayList 某个方法的源码
可以看到,内部是通过使用ReentrantLock实现的线程安全。
简单用一用:
public static void main(String[] args)
CopyOnWriteArrayList<String> stringCopyOnWriteArrayList = new CopyOnWriteArrayList<>();
for (int i = 0; i < 20; i++)
int finalI = i;
new Thread(() ->
stringCopyOnWriteArrayList.add(String.valueOf(finalI));
System.out.println("strings = " + stringCopyOnWriteArrayList);
).start();
运行看下效果:
可以看到,也不会出现并发修改异常。
如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!
以上是关于Java中线程安全的集合的主要内容,如果未能解决你的问题,请参考以下文章