在java中,有一个专门用来处理并发容器的包:java.util.concurrent 包,其中有一个CopyOnWriteArrayList类,相当于ArrayList的线程安全版。
我们可以使用它代替ArrayList,就无需加synchronized来锁线程了。
注:本节内容了解即可(面试用),因为这是高级并发才会使用的,后期再来补充本文。
先拿之前1w个线程往ArrayList容器添加内容的例子来看。
代码:
package _20191205;
import java.util.List;
import java.util.ArrayList;
public class SynBlockTest02 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
for(int i = 0;i < 10000;i++ ) {
new Thread(()->{
synchronized (list) {//重点在这里,synchronized代码要与被锁的对象被修改的地方尽可能近
list.add(Thread.currentThread().getName().toString());
}
},"线程"+i).start();
}
System.out.println("8s后输出结果");
try {
Thread.sleep(8000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}
然后我们就可以修改为线程版的ArrayList:
导包,把ArrayList替换为CopyOnWriteArrayList,删掉synchronized同步块。
package _20191205;
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
public class SynBlockTest06 {
public static void main(String[] args) {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
for(int i = 0;i < 10000;i++ ) {
new Thread(()->{
list.add(Thread.currentThread().getName().toString());
},"线程"+i).start();
}
System.out.println("8s后输出结果");
try {
Thread.sleep(8000);
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(list.size());
}
}