Java集合并发安全面试题
同步包装器
Q1: Collections的同步包装器是如何实现线程安全的?
java">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的实现原理是什么?
java">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的使用场景是什么?
java">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: 阻塞队列的实现类有哪些?它们的特点是什么?
java">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: 如何选择合适的并发集合类?
java">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: 如何实现自定义的线程安全集合?
java">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的应用场景
- 熟悉阻塞队列的使用方式
- 掌握不同并发集合的选择标准
- 理解读写锁的使用场景
- 能够实现自定义线程安全集合
- 注意并发集合的性能影响