Java集合并发安全面试题
同步包装器
Q1: Collections的同步包装器是如何实现线程安全的?
public class SynchronizedWrapperExample {
public void demonstrateSynchronizedCollections() {
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());
Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());
synchronized (syncList) {
Iterator<String> iterator = syncList.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
public class SimpleSynchronizedList<E> {
private final List<E> list;
private final Object mutex;
public SimpleSynchronizedList(List<E> list) {
this.list = list;
this.mutex = this;
}
public boolean add(E e) {
synchronized (mutex) {
return list.add(e);
}
}
public E get(int index) {
synchronized (mutex) {
return list.get(index);
}
}
public E remove(int index) {
synchronized (mutex) {
return list.remove(index);
}
}
}
}
并发集合类
Q2: ConcurrentHashMap的实现原理是什么?
public class ConcurrentHashMapExample {
public void demonstrateConcurrentHashMap() {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("A", 1);
map.putIfAbsent("B", 2);
map.replace("A", 1, 3);
for (Map.Entry<String, Integer> entry : map.entrySet()) {
map.put("C", 3);
}
}
public class ConcurrentCounterExample {
private ConcurrentHashMap<String, AtomicInteger> counters =
new ConcurrentHashMap<>();
public void incrementCounter(String key) {
counters.computeIfAbsent(key, k -> new AtomicInteger(0))
.incrementAndGet();
}
public int getCount(String key) {
AtomicInteger counter = counters.get(key);
return counter == null ? 0 : counter.get();
}
}
}
Q3: CopyOnWriteArrayList的使用场景是什么?
public class CopyOnWriteArrayListExample {
public void demonstrateCopyOnWrite() {
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
list.add("A");
list.add("B");
for (String item : list) {
System.out.println(item);
list.add("C");
}
}
public class EventListenerRegistry {
private final CopyOnWriteArrayList<EventListener> listeners =
new CopyOnWriteArrayList<>();
public void addEventListener(EventListener listener) {
listeners.add(listener);
}
public void removeEventListener(EventListener listener) {
listeners.remove(listener);
}
public void fireEvent(Event event) {
for (EventListener listener : listeners) {
listener.onEvent(event);
}
}
}
}
阻塞队列
Q4: 阻塞队列的实现类有哪些?它们的特点是什么?
public class BlockingQueueExample {
public void demonstrateArrayBlockingQueue() {
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
new Thread(() -> {
try {
queue.put("A");
queue.put("B");
queue.put("C");
queue.put("D");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
new Thread(() -> {
try {
String item = queue.take();
System.out.println("Consumed: " + item);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
}
public class ProducerConsumerExample {
private final BlockingQueue<Task> taskQueue;
public ProducerConsumerExample(int capacity) {
this.taskQueue = new LinkedBlockingQueue<>(capacity);
}
public void produce(Task task) throws InterruptedException {
taskQueue.put(task);
}
public Task consume() throws InterruptedException {
return taskQueue.take();
}
public void startWorker() {
new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Task task = consume();
task.process();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
}
}
}
并发安全策略
Q5: 如何选择合适的并发集合类?
public class ConcurrentCollectionSelectionExample {
public void demonstrateSelection() {
ConcurrentHashMap<String, String> concurrentMap =
new ConcurrentHashMap<>();
CopyOnWriteArrayList<String> copyOnWriteList =
new CopyOnWriteArrayList<>();
BlockingQueue<Task> blockingQueue =
new LinkedBlockingQueue<>();
ConcurrentSkipListMap<String, String> skipListMap =
new ConcurrentSkipListMap<>();
}
public void performanceComparison() {
Map<String, String> syncMap =
Collections.synchronizedMap(new HashMap<>());
ConcurrentHashMap<String, String> concurrentMap =
new ConcurrentHashMap<>();
Runnable syncMapTest = () -> {
for (int i = 0; i < 1000; i++) {
syncMap.put("key" + i, "value" + i);
}
};
Runnable concurrentMapTest = () -> {
for (int i = 0; i < 1000; i++) {
concurrentMap.put("key" + i, "value" + i);
}
};
}
}
Q6: 如何实现自定义的线程安全集合?
public class CustomThreadSafeCollectionExample {
public class SynchronizedList<E> {
private final List<E> list = new ArrayList<>();
public synchronized boolean add(E element) {
return list.add(element);
}
public synchronized E get(int index) {
return list.get(index);
}
public synchronized boolean remove(E element) {
return list.remove(element);
}
}
public class ReadWriteList<E> {
private final List<E> list = new ArrayList<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
public boolean add(E element) {
writeLock.lock();
try {
return list.add(element);
} finally {
writeLock.unlock();
}
}
public E get(int index) {
readLock.lock();
try {
return list.get(index);
} finally {
readLock.unlock();
}
}
}
public class StampedList<E> {
private final List<E> list = new ArrayList<>();
private final StampedLock lock = new StampedLock();
public boolean add(E element) {
long stamp = lock.writeLock();
try {
return list.add(element);
} finally {
lock.unlockWrite(stamp);
}
}
public E get(int index) {
long stamp = lock.tryOptimisticRead();
E value = list.get(index);
if (!lock.validate(stamp)) {
stamp = lock.readLock();
try {
value = list.get(index);
} finally {
lock.unlockRead(stamp);
}
}
return value;
}
}
}
面试关键点
- 理解同步包装器的实现原理
- 掌握ConcurrentHashMap的特性
- 了解CopyOnWriteArrayList的应用场景
- 熟悉阻塞队列的使用方式
- 掌握不同并发集合的选择标准
- 理解读写锁的使用场景
- 能够实现自定义线程安全集合
- 注意并发集合的性能影响