juc-06

集合类与多线程

管理多个实例的接口或类统称为集合(collection)。

Java中的大部分集合都是非线程安全的。因此,在多线程操作集合的时候,需要去查看API文档, 确认要用的类或接口是否线程安全的。

例子1:非线程安全的java.util.ArrayList类

该例子中ArrayList(及迭代器)在被多个线程同时读写而失去安全性时,便会抛出ConcurrentModificationException异常。
该运行时(runtime)的异常用于表示“执行并发修改了”。

异常不过是调查Bug根本原因的提示而已,所以编写编程不能依赖于抛出的异常。

集合类与多线程-例子
例子

例子2: 利用Collections.synchronized方法所进行的同步

对例子1的改造,使得其具有安全性。

例子2

  • 通过Collections.synchronizedList方法同步ArrayList实例
  • 通过使用list同步后的读线程
    • “写”线程是显示调用add方法和remove方法,故可以不做调整。
1
2
3
4
5
synchronized(list){
for(int n : list){
System.out.println(n);
}
}

例子3: 使用写时复制(copy-on-write)的java.util.concurrent.CopyOnWriteArrayList类

例子2使用Collections.synchronized进行同步。
这里使用CopyOnWriteArrayList类通过copy-on-write避免读写冲突。

1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
//这里使用Copy-on-write
final List<Integer> list = new CopyOnWriteArrayList<Integer>();
new WriterThread(list).start();
new ReaderThread(list).start();
}
}

程序如果频繁“写”操作,使用copy-on-write会比较耗时,如果写操作比较少,读操作比较多,是比较适合使用的。

作者

Mozss

发布于

2020-01-23

许可协议

评论