开发者

一文详解Java线程安全的集合有哪些

开发者 https://www.devze.com 2025-06-03 10:19 出处:网络 作者: +720
目录1. 阻塞队列 (blockingQueue)2. 并发 Map (ConcurrentMap)3. 并发 Set (ConcurrentSet)4. 并发 List (ConcurrentList)5. 其他总结:问题分析:
目录
  • 1. 阻塞队列 (blockingQueue)
  • 2. 并发 Map (ConcurrentMap)
  • 3. 并发 Set (ConcurrentSet)
  • 4. 并发 List (ConcurrentList)
  • 5. 其他
  • 总结:
  • 问题分析:

一文详解Java线程安全的集合有哪些

Java 提供了多种线程安全的集合,它们位于 java.util.concurrent 包下,主要分为以下几类:

1. 阻塞队列 (BlockingQueue)

阻塞队列是一种特殊的队列,当队列为空时,获取元素的操作会被阻塞,直到队列中有元素可用;当队列已满时,添加元素的操作会被阻塞,直到队列中有空闲位置。

  • ArrayBlockingQueue: 基于数组的有界阻塞队列,按照 FIFO(先进先出)原则对元素进行排序。
  • LinkedBlockingQueue: 基于链表的可选有界阻塞队列(默认无界),按照 FIFO 原则对元素进行排序。
  • PriorityBlockingQueue:&nbspythonp;无界阻塞队列,支持优先级排序。
  • SynchronousQueue: 同步队列,不存储元素,每个插入操作必须等待另一个线程的移除操作,反之亦然。
  • DelayQueue: 无界阻塞队列,只有在延迟期满时才能从中提取元素。
  • LinkedTransferQueue: 一个编程客栈由链表结构组成的无界阻塞队列,它在SynchronousQueue的基础上添加了transfer方法。

代码示例 (ArrayBlockingQueue):

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);

        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 20; i++) {
                    queue.put("Item " + i); // 如果队列满了,会阻塞
                    System.out.println("Produced: Item " + i);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                for (int ipsZRCbYa = 0; i < 20; i++) {
                    String item = queue.take(); // 如果队列为空,会阻塞
                    System.out.println("Consumed: " + item);
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        producer.start();
        consumer.start();
    }
}

2. 并发 Map (ConcurrentMap)

ConcurrentMap 接口是&nb编程客栈sp;Map 接口的子接口,提供了线程安全的并发操作。

  • ConcurrentHashMap: 基于哈希表的线程安全 Map 实现,使用分段锁(JDK 1.7)或 CAS + synchronized (JDK 1.8+) 来实现并发控制。
  • ConcurrentSkipListMap: 基于跳表 (Skip List) 的线程安全 Map 实现,支持排序。

代码示例 (ConcurrentHashMap):

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

        // 多个线程并发地向 map 中添加元素
        Runnable task = () -> {
            for (int i = 0; i < 1000; i++) {
          编程客栈      map.putIfAbsent("Key" + i, i); // 原子操作
            }
        };

        Thread thread1 = new Thread(task);
        Thread thread2 = new Thread(task);

        thread1.start();
        thread2.start();
    }
}

3. 并发 Set (ConcurrentSet)

  • ConcurrentSkipListSet: 基于跳表的线程安全的Set,支持排序。
  • CopyOnWriteArraySet: 基于 CopyOnWriteArrayList 实现的线程安全 Set。

4. 并发 List (ConcurrentList)

  • CopyOnWriteArrayList: 线程安全的 List 实现,通过 写时复制 (Copy-On-Write) 的方式来实现并发控制。每次修改操作都会创建一个新的数组副本,读操作在原来的数组上进行,因此读操作不需要加锁,可以并发进行。适用于读多写少的场景。

代码示例 (CopyOnWriteArrayList):

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyOnWriteArrayListExample {
    public static void main(String[] args) {
        List<String> list = new CopyOnWriteArrayList<>();

        // 读线程
        Runnable reader = () -> {
            for (String item : list) {
                System.out.println("Read: " + item);
            }
        };

        // 写线程
        Runnable writer = () -> {
            list.add("New Item");
            System.out.println("Added: New Item");
        };
    }
}

5. 其他

  • Collections.synchronizedXXX 方法: Collections 工具类提供了一些静态方法,可以将非线程安全的集合包装成线程安全的集合,例如:
    • Collections.synchronizedList(List<T> list)
    • Collections.synchronizedSet(Set<T> s)
    • Collections.synchronizedMap(Map<K,V> m)这些方法通过在每个方法上添加 synchronized 关键字来实现线程安全,性能较低。

总结:

Java 并发包提供了丰富的线程安全集合,可以满足不同的并发编程需求。选择合适的线程安全集合需要考虑以下因素:

  • 数据结构: 数组、链表、哈希表、跳表等。
  • 是否有界: 有界、无界。
  • 排序: 是否需要排序。
  • 读写比例: 读多写少、写多读少、读写均衡。
  • 性能要求: 对并发性能的要求。

问题分析:

这个问题考察了 Java 中线程安全集合的种类和用法。

与其他问题的知识点联系:

  • Java 线程安全的集合有哪些? 这是对 Java 并发集合的整体了解。
  • Java 中的 synchronized 是怎么实现的? Collections.synchronizedXXX 方法使用了 synchronized 关键字。
  • Java 中 ReentrantLock 的实现原理是什么? 一些并发集合(如 ArrayBlockingQueue)内部使用了 ReentrantLock
  • 什么是 Java 的 CAS(Compare-And-Swap)操作? 一些并发集合(如 ConcurrentHashMap)使用了 CAS 操作。
  • 你使用过 Java 中的哪些阻塞队列? 阻塞队列是线程安全集合的重要组成部分。

理解这些联系可以帮助你更全面地掌握 Java 并发编程的知识,并了解如何在实际应用中选择合适的线程安全集合。

到此这篇关于Java线程安全集合有哪些的文章就介绍到这了,更多相关Java线程安全的集合内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号