同步容器和并发容器

简介: 同步容器和并发容器

公众号merlinsea


  • 同步容器
  • 同步容器:同步容器在java中包括有Vector,HashTable,Collections.syncronizedXXX
  • 当多个线程去操作同一个同步容器的时候,调用这个同步容器的方法会持有同一把锁,在Vector中是持有this锁,在Collections.syncronizedXXX中是持有mutex锁。因此在多线程环境下可能存在线程不安全的问题
  • 下面以Vector为例作为讲解:单线程环境下使用Vector同步容器:这种用法是没有问题的,不存在线程不安全的问题。但由于Vector每一方法都使用了syncronized的关键字,在这种情况下性能不如ArrayList集合。


public class VectorDemo {
    public static void main(String[] args) {
        Vector<String> stringVector = new Vector<>();
        for (int i = 0; i < 1000; i++) {
            stringVector.add("demo" + i);
        }
        //正确迭代
        Iterator<String> stringIterator = stringVector.iterator();
        while (stringIterator.hasNext()) {
            String next = stringIterator.next();
            if (next.equals("demo2")) {
                stringIterator.remove();
            }
        }
    }
}


多线程环境下使用Vector同步容器:这种用法存在线程安全问题

640.jpg


如何保证多线程环境下操作同一个Vector依旧是线程安全的呢?

外部额外加锁。 通常会选择锁住迭代器


public class VectorDemo {
    public static void main(String[] args) {
        Vector<String> stringVector = new Vector<>();
        for (int i = 0; i < 1000; i++) {
            stringVector.add("demo" + i);
        }
        Iterator<String> stringIterator = stringVector.iterator();
        for (int i = 0; i < 4; i++) {
            new Thread(() -> {
                synchronized (stringIterator) {
                    while (stringIterator.hasNext()) {
                        String next = stringIterator.next();
                        if (next.equals("demo2")) {
                            stringIterator.remove();
                        }
                    }
                }
            }).start();
        }
    }
}


综合上述的问题,


Vector在单线程环境下不存在线程安全问题,因此不需要内部每一个方法都加syncronized修饰,因此性能不如ArrayList集合。


Vector在多线程环境下存在线程安全问题,因此外部需要额外加锁保证线程安全,但外部额外加上了syncronized修饰,syncronized代码块中的函数其实也就没有必要在加锁了,因此在多线程环境下依旧可以通过包装ArrayList实现比vector性能更好的同步容器。


以上就是Vector为啥被废弃的原因。


  • 并发容器
  • 并发容器:并发容器在java中包括有CopyOnWrite系列,Concurrent系列和BlockingQueue系列
  • 当多个线程去操作同一个并发容器的时候,会先拷贝一个并发容器的副本,然后对副本操作,最后根据cas操作进行判断然后写回原来的并发容器中。
  • 下面是多线程操作同一个CopyOnWriteArrayList的例子(线程安全)


public class Demo {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> strings = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 1000; i++) {
            strings.add("demo" + i);
        }
        for (int i = 0; i < 4; i++) {
            new Thread(() -> {
                strings.forEach(e -> {
                    if (e.equals("demo2")) {
                        /**
                         * 这里不会发生线程安全问题,remove操作是在副本中操作,然后再根据cas原理写回主存
                         */
                        strings.remove(e);
                    }
                });
            }).start();
        }
    }
}


vip算法班永久学习班: 800元/人

周一、周三、周五:8:30-9:30,周六、周日:10:30-11:30

报名方式:通过公众号导航栏的刷题群即可联系到我的微信号

vip算法班详情链接

奔跑的小梁,公众号:梁霖编程工具库算法训练营快来参加吧~
相关文章
|
25天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
5月前
|
安全 程序员 C++
C++一分钟之-C++中的并发容器
【7月更文挑战第17天】C++11引入并发容器,如`std::shared_mutex`、`std::atomic`和线程安全的集合,以解决多线程中的数据竞争和死锁。常见问题包括原子操作的误用、锁的不当使用和迭代器失效。避免陷阱的关键在于正确使用原子操作、一致的锁管理以及处理迭代器失效。通过示例展示了如何安全地使用这些工具来提升并发编程的安全性和效率。
72 1
|
5月前
|
缓存 安全 Java
Java中的并发容器:ConcurrentHashMap详解
Java中的并发容器:ConcurrentHashMap详解
|
5月前
|
安全 Java 容器
第一篇:并发容器学习开篇介绍
第一篇:并发容器学习开篇介绍
42 4
|
5月前
|
存储 安全 算法
(九)深入并发编程之并发容器:阻塞队列、写时复制容器、锁分段容器原理详谈
相信大家在学习JavaSE时都曾接触过容器这一内容,一般Java中的容器可分为四类:Map、List、Queue以及Set容器,而在使用过程中,对于ArrayList、HashMap等这类容器都是经常使用的,但问题在于这些容器在并发环境下都会存在线程安全问题。
|
7月前
|
安全 Java 容器
Java一分钟之-并发编程:并发容器(ConcurrentHashMap, CopyOnWriteArrayList)
【5月更文挑战第18天】本文探讨了Java并发编程中的`ConcurrentHashMap`和`CopyOnWriteArrayList`,两者为多线程数据共享提供高效、线程安全的解决方案。`ConcurrentHashMap`采用分段锁策略,而`CopyOnWriteArrayList`适合读多写少的场景。注意,`ConcurrentHashMap`的`forEach`需避免手动同步,且并发修改时可能导致`ConcurrentModificationException`。`CopyOnWriteArrayList`在写操作时会复制数组。理解和正确使用这些特性是优化并发性能的关键。
69 1
|
7月前
|
存储 缓存 安全
Golang深入浅出之-Go语言中的并发安全容器:sync.Map与sync.Pool
Go语言中的`sync.Map`和`sync.Pool`是并发安全的容器。`sync.Map`提供并发安全的键值对存储,适合快速读取和少写入的情况。注意不要直接遍历Map,应使用`Range`方法。`sync.Pool`是对象池,用于缓存可重用对象,减少内存分配。使用时需注意对象生命周期管理和容量控制。在多goroutine环境下,这两个容器能提高性能和稳定性,但需根据场景谨慎使用,避免不当操作导致的问题。
207 7
|
6月前
|
安全 Java 大数据
Java性能优化(七)-多线程调优-并发容器的使用
Java性能优化(七)-多线程调优-并发容器的使用
61 0
|
7月前
|
JSON 机器人 Linux
Docker_volume(容器和宿主同步数据)
Docker_volume(容器和宿主同步数据)
62 2
|
7月前
|
存储 算法 Java
12张图一次性搞懂高性能并发容器ConcurrentLinkedQueue
12张图一次性搞懂高性能并发容器ConcurrentLinkedQueue