【JUC —— 05 线程安全集合类】

在Java中,线程安全的集合类通过多种机制确保在多线程环境下操作集合时不会发生数据竞争或不一致的情况。下面是一些常见的线程安全集合类及其实现线程安全的方式:

1. Vector 和 Hashtable

  • Vector 和 Hashtable 是早期版本的Java中的线程安全集合类。
  • 它们通过在每个方法上使用synchronized关键字来实现线程安全。
  • 这意味着每个方法在执行时都会获得对象的锁,从而保证同一时间只有一个线程可以访问这些方法。
  • 虽然这种方法保证了线程安全,但在高并发情况下会导致较高的锁竞争,进而可能导致性能瓶颈。
Vector<Integer> vector = new Vector<>();
vector.add(1);
vector.add(2);

Hashtable<String, String> hashtable = new Hashtable<>();
hashtable.put("key", "value");

2. Collections.synchronizedList 和 Collections.synchronizedMap等

  • Java提供了Collections类中的静态方法来创建线程安全的集合。
  • 这些方法返回的集合通过内部锁机制确保线程安全。
  • 这些方法也通过在每个方法上使用synchronized关键字来实现线程安全,与VectorHashtable类似。
List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
synchronizedList.add(1);
synchronizedList.add(2);

Map<String, String> synchronizedMap = Collections.synchronizedMap(new HashMap<>());
synchronizedMap.put("key", "value");

// jdk 17 源码
public void add(int index, E element) {
    synchronized (mutex) {
        list.add(index, element);
    }
}

3. CopyOnWriteArrayList 和 CopyOnWriteArraySet

  • CopyOnWriteArrayList 和 CopyOnWriteArraySet 是通过“写时复制”机制实现线程安全的。
  • 当发生写操作时(如添加或删除元素),它们会创建一个新的底层数组,并在新数组上执行修改操作。读操作则不需要加锁,因此在读多写少的场景下性能较高。
CopyOnWriteArrayList<Integer> cowList = new CopyOnWriteArrayList<>();
cowList.add(1);
cowList.add(2);

CopyOnWriteArraySet<Integer> cowSet = new CopyOnWriteArraySet<>();
cowSet.add(1);
cowSet.add(2);


// jdk 17 源码:
public boolean add(E e) {
        synchronized (lock) {
            Object[] es = getArray();
            int len = es.length;
            es = Arrays.copyOf(es, len + 1);
            es[len] = e;
            setArray(es);
            return true;
        }
    }

4. ConcurrentHashMap

  • ConcurrentHashMap 是一个高效的线程安全Map实现。
  • 它通过分段锁(Segmented Locking)机制来实现线程安全,
  • 即将整个Map分为多个段(Segment),每个段有自己的锁。
  • 这样,在高并发情况下,不同的线程可以并发地访问不同的段,从而提高并发性能。
ConcurrentHashMap<String, String> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("key", "value");

5. BlockingQueue

  • Java的并发包(java.util.concurrent)提供了多种阻塞队列,
  • ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueue
  • 这些队列在插入和移除元素时使用内部锁来确保线程安全,并提供了线程间通信的机制。
BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(10);
blockingQueue.put(1);
blockingQueue.take();

阻塞队列的工作原理主要依赖于以下两个方面:

  1. 内部锁(Intrinsic Lock):用于确保对队列的操作是线程安全的。
  2. 条件变量(Condition Variables):用于管理线程的等待和唤醒。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值