主题
面试速答(先看这里)
**一句话结论:**Java1.5并发包(java.util.concurrent)包含线程安全集合类,允许在迭代时修改集合。
60秒标准回答:
Java1.5并发包(java.util.concurrent)包含线程安全集合类,允许在迭代时修改集合
Java并发集合类主要包含以下几种
**答题顺序:**结论 → 原理/机制 → 关键流程 → 场景与取舍 → 易错点
回答主线:
- **要点1:**Java并发集合类主要包含以下几种:
**记忆锚点:**Java → ConcurrentLinkedDeque → ConcurrentLinkedQueue → ConcurrentSkipListMap → ConcurrentSkipListSet → CopyOnWriteArrayList
易错提醒:
- 在调用集合前,使用synchronized或者ReentrantLock对代码加锁(读写都要加锁) 使用ThreadLocal,将集合放到线程内访问,但是这样集合中的值就不能被其他线程访问了 使用Collections.synchronizedXXX()方法,可以获得一个线程安全的集合 使用不可变集合进行封装,当集合是不可变的时候,自然是线程安全的 Java…
追问准备:
- 围绕「Java」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「ConcurrentLinkedDeque」:底层原理是什么?使用时有哪些边界和常见坑?
- 围绕「ConcurrentLinkedQueue」:底层原理是什么?使用时有哪些边界和常见坑?
- 如果线上出现异常,你会如何定位、验证并规避?
典型回答
- 在调用集合前,使用synchronized或者ReentrantLock对代码加锁(读写都要加锁)
latex
public class SynchronizedCollectionExample {
private List<Integer> list = new ArrayList<>();
public void add(int value) {
synchronized (SynchronizedCollectionExample.class) {
list.add(value);
}
}
public int get(int index) {
synchronized (SynchronizedCollectionExample.class) {
return list.get(index);
}
}
}- 使用ThreadLocal,将集合放到线程内访问,但是这样集合中的值就不能被其他线程访问了
latex
public class ThreadLocalCollectionExample {
private ThreadLocal<List<Integer>> threadLocalList = ThreadLocal.withInitial(ArrayList::new);
public void add(int value) {
threadLocalList.get().add(value);
}
public int get(int index) {
return threadLocalList.get().get(index);
}
}- 使用Collections.synchronizedXXX()方法,可以获得一个线程安全的集合
latex
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
public class CollectionsSynchronizedExample {
List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<Integer>());
public void add(int value) {
synchronizedList.add(value);
}
public int get(int index) {
return synchronizedList.get(index);
}
}- 使用不可变集合进行封装,当集合是不可变的时候,自然是线程安全的
latex
import com.google.common.collect.ImmutableList;
public class ImmutableCollectionExample {
private ImmutableList<Integer> immutableList = ImmutableList.of(1, 2, 3);
public int get(int index) {
return immutableList.get(index);
}
}或者:
latex
import java.util.List;
public class ImmutableJava9Example {
private List<Integer> immutableList = List.of(1, 2, 3);
public int get(int index) {
return immutableList.get(index);
}
}扩展知识
Java有哪些线程安全的集合?
Java1.5并发包(java.util.concurrent)包含线程安全集合类,允许在迭代时修改集合。
Java并发集合类主要包含以下几种:
- ConcurrentHashMap
- ConcurrentLinkedDeque
- ConcurrentLinkedQueue
- ConcurrentSkipListMap
- ConcurrentSkipListSet
- CopyOnWriteArrayList
- CopyOnWriteArraySet