Java集合并发安全面试题

news/2025/2/25 22:17:23

Java集合并发安全面试题

同步包装器

Q1: Collections的同步包装器是如何实现线程安全的?

java">public class SynchronizedWrapperExample {
    // 1. 基本使用
    public void demonstrateSynchronizedCollections() {
        // 创建同步List
        List<String> syncList = Collections.synchronizedList(new ArrayList<>());
        
        // 创建同步Set
        Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());
        
        // 创建同步Map
        Map<String, String> syncMap = Collections.synchronizedMap(new HashMap<>());
        
        // 正确的遍历方式
        synchronized (syncList) {
            Iterator<String> iterator = syncList.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
        }
    }
    
    // 2. 同步包装器的实现原理
    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 {
    // 1. 基本使用
    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()) {
            // 迭代时可以修改,不会抛出ConcurrentModificationException
            map.put("C", 3);
        }
    }
    
    // 2. 常见使用场景
    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 {
    // 1. 基本使用
    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");
        }
    }
    
    // 2. 事件监听器列表
    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 {
    // 1. ArrayBlockingQueue示例
    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();
    }
    
    // 2. 生产者-消费者模式
    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 {
    // 1. 不同场景的选择
    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<>();
    }
    
    // 2. 性能对比
    public void performanceComparison() {
        // 同步Map
        Map<String, String> syncMap = 
            Collections.synchronizedMap(new HashMap<>());
            
        // 并发Map
        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 {
    // 1. 使用synchronized关键字
    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);
        }
    }
    
    // 2. 使用ReentrantReadWriteLock
    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();
            }
        }
    }
    
    // 3. 使用StampedLock
    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;
        }
    }
}

面试关键点

  1. 理解同步包装器的实现原理
  2. 掌握ConcurrentHashMap的特性
  3. 了解CopyOnWriteArrayList的应用场景
  4. 熟悉阻塞队列的使用方式
  5. 掌握不同并发集合的选择标准
  6. 理解读写锁的使用场景
  7. 能够实现自定义线程安全集合
  8. 注意并发集合的性能影响

http://www.niftyadmin.cn/n/5865987.html

相关文章

FreeRTOS--入门学习-移植

FreeRTOS-入门学习-移植 FreeRTOS-下载FreeRTOS-具体文件介绍工程创建并使用移植成功--使用FreeRTOS手册帮助开发 FreeRTOS-下载 使用官网需要科学上网&#xff0c;我们这里使用其他国内的下载地址 下载202212.00版本 下载地址&#xff1a;https://sourceforge.net/projects/f…

多线程的案例之线程池 [Java EE 多线程]

目录 1. 什么是线程池 1.1 定义 1.2 工作原理 1.3 优点 1.4 举例 2. 标准库中的线程池 2.1 创建线程池 2.2 Executors 创建线程池的几种方式 2.3 ThreadPoolExecutor 提供了更多的可选参数, 可以进一步细化线程池行为的设定 3. 实现线程池 3.1 主要操作说明 3.2 代…

java给钉钉邮箱发送邮件

1.开通POP和IMAP 2.引入pom <dependency><groupId>javax.mail</groupId><artifactId>mail</artifactId><version>1.4.7</version> </dependency>3.逻辑 String host "smtp.qiye.aliyun.com"; String port "…

C#中提供的多种集合类以及适用场景

在 C# 中&#xff0c;有多种集合类可供使用&#xff0c;它们分别适用于不同的场景,部分代码示例提供了LeetCode相关的代码应用。 1. 数组&#xff08;Array&#xff09; 特点 固定大小&#xff1a;在创建数组时需要指定其长度&#xff0c;之后无法动态改变。连续存储&#xf…

深度学习-6.用于计算机视觉的深度学习

Deep Learning - Lecture 6 Deep Learning for Computer Vision 简介深度学习在计算机视觉领域的发展时间线 语义分割语义分割系统的类型上采样层语义分割的 SegNet 架构软件中的SegNet 架构数据标注 目标检测与识别目标检测与识别问题两阶段和一阶段目标检测与识别两阶段检测器…

.manifest是什么文件格式

.manifest 文件是一种用于描述应用程序或组件元数据的文件&#xff0c;其格式和内容因平台和应用类型而异。在某些情况下&#xff0c;.manifest 文件采用 JSON 格式&#xff0c;例如在 Web 应用程序中&#xff0c;manifest.json 文件用于定义应用的名称、版本、图标、启动页面等…

04基于vs2022的c语言笔记——数据类型

目录 前言 4.数据类型 4-1数据类型初识 4-2数据类型之整型 4-3 sizeof的应用 4-4unsigned的应用 4-5实型/浮点型 4-6字符型 4-7转义字符 4-8字符串初识 4-9-1 输入之 整数的输入 提示&#xff1a; 本节代码部分 1.scanf的基本用法介绍 2.两个变量的输入 3.输…

Python 学习之旅:高级阶段(十六)Web 开发之路由和视图函数

在 Python 的 Web 开发领域,路由和视图函数是构建 Web 应用不可或缺的部分。它们就像是 Web 应用的 “交通枢纽” 和 “服务窗口”,路由负责引导用户请求到达正确的处理地点,而视图函数则负责处理这些请求并返回相应的响应。接下来,我们将以 Flask 框架为例,深入了解路由和…