0


【Java集合类不安全示例】

文章目录


提示:以下是本篇文章正文内容,下面案例可供参考

一、List

代码如下(示例):

publicclassZZZZZZZZZZ{publicstaticvoidmain(String[] args){// ArrList 非线程安全的集合List<String> list1 =newArrayList<>();for(int i =0; i <30; i++){newThread(()->{// 多个线程同时向 ArrayList 添加元素
                list1.add(UUID.randomUUID().toString().substring(0,8));System.out.println(list1);}).start();}}}

输出结果

Exception in thread “Thread-1” Exception in thread “Thread-0” Exception in thread “Thread-4” Exception in thread “Thread-25” Exception in thread “Thread-23” Exception in thread “Thread-17” Exception in thread “Thread-18” Exception in thread “Thread-27”

java.util.ConcurrentModificationException

并发修改异常,由于ArrayList 不是线程安全的容器,多个线程并发添加元素,会导致竞争现象,最终产生该异常

故障出现

java.util.ConcurrentModificationException

导致原因

多线程并发争抢修改导致

解决方法

  • 使用线程安全的容器,例如:Vector,在该类中每个方法都加上了 synchronized,不会导致线程安全问题,但是由于锁的粒度太细,会导致程序的速度较慢。
  • 使用集合工具类的线程安全的方法,如:
static<T>List<T>Collections.synchronizedList(List<T> list)
  • juc 下面的 CopyOnWriteArrayList,该类使用使用 ReentrantLock 加锁解锁,每次添加新元素就会加锁,然后开辟比旧数组多1的空间,将原数组全部拷贝进去,再将新元素加到最后一个位置。由于每次添加元素都会拷贝原数组,如果原数组很大,就会对内存资源造成很大的消耗,因此适合读多写少的场景。源码如下:
publicbooleanadd(E e){finalReentrantLock lock =this.lock;
                  lock.lock();try{Object[] elements =getArray();int len = elements.length;Object[] newElements =Arrays.copyOf(elements, len +1);
                      newElements[len]= e;setArray(newElements);returntrue;}finally{
                      lock.unlock();}}

二、Set

代码如下(示例):

publicclassZZZZZZZZZZ{publicstaticvoidmain(String[] args){// 非线程安全的 HashSetSet<String> set =newHashSet<>();for(int i =0; i <30; i++){newThread(()->{
                set.add(UUID.randomUUID().toString().substring(0,8));System.out.println(set);}).start();}}}

故障出现

java.util.ConcurrentModificationException

导致原因

多线程并发争抢修改导致

解决方法

  • 使用集合工具类的线程安全的方法,如:
static<T>Set<T>Collections.synchronizedList(Set<T> s)
  • juc 下面的 CopyOnWriteArraySet,底层还是 CopyOnWriteArrayList,源码的构造方法如下:
publicCopyOnWriteArraySet(){
        al =newCopyOnWriteArrayList<E>();}

三、Map

代码如下(示例):

publicclassZZZZZZZZZZ{publicstaticvoidmain(String[] args){// 非线程安全的 HashMapMap<String,String> map =newHashMap<>();for(int i =0; i <30; i++){newThread(()->{
                map.put(Thread.currentThread().getName(),UUID.randomUUID().toString().substring(0,8));System.out.println(map);}).start();}}}

故障出现

java.util.ConcurrentModificationException

导致原因

多线程并发争抢修改导致

解决方法

  • 使用线程安全的容器,如:ConcurrentHashMap
  • 使用集合工具类的线程安全的方法,如:
static<K,V>Map<K,V>Collections.synchronizedMap(Map<K,V> m)
标签: java 安全 windows

本文转载自: https://blog.csdn.net/m0_69269392/article/details/135254639
版权归原作者 学习愚公 所有, 如有侵权,请联系我们删除。

“【Java集合类不安全示例】”的评论:

还没有评论