常用集合线程安全分析

这篇具有很好参考价值的文章主要介绍了常用集合线程安全分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ArrayList在多线程情况下,不安全

具体代码
package com.shaonian.juc.list_thread_secure;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author 长名06
 * @version 1.0
 * 演示ArrayList集合线程不安全
 */
public class ListDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                //会出现java.util.ConcurrentModificationException 并发修改异常
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}

解决方案

使用Vector/ConcurrentHashMap集合
package com.shaonian.juc.list_thread_secure;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.Vector;

/**
 * @author 长名06
 * @version 1.0
 * Vector集合,线程安全 不推荐使用
 */
public class VectorDemo {
    public static void main(String[] args) {
        List<String> list = new Vector<>();

        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}

使用Collections中的synchronizedList()/synchronizedMap()

package com.shaonian.juc.list_thread_secure;

import java.util.*;

/**
 * @author 长名06
 * @version 1.0
 * 使用Collections中的synchronizedList方法,转成对应线程安全的集合,不推荐使用
 */
public class CollectionsDemo {
    public static void main(String[] args) {
        List<String> list = Collections.synchronizedList(new ArrayList<>());
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}

使用CopyOnwriteArrayList

涉及到写时复制技术,就是说,此集合是可以并发读,但是写操作,同时只能有一个线程执行。写操作时,先将原有的集合内容,copy一份,然后写入新的内容,然后再覆盖原有的集合,覆盖后的集合,就可以读和写了

package com.shaonian.juc.list_thread_secure;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author 长名06
 * @version 1.0
 * 使用线程安全的集合如CopyOnWriteArrayList
 */
public class CopyOnWriteArrayListDemo {
    public static void main(String[] args) {
        List<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 30; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(list);
            }, String.valueOf(i)).start();
        }
    }
}

CopyOnWriteList

CopyOnWriteList相当于线程安全的ArrayList,和ArrayList一样,它是个可变数组,不过有一下特性

  • 1.它最适合具有以下特征的程序使用,List大小通常保持很小,读操作远多于写操作,需要再遍历期间防止线程间的冲突。
  • 2.线程安全。
  • 3.可变操作,需要复制整个数组,所以可变操作(add(),set(),remove()等)操作开销大。
  • 4.迭代器支持hasNext(),next()等不可变操作,但是不支持remove()等操作。
  • 5.使用迭代器进行遍历的速度会很快,并且不会和其他线程发生冲突,再构造迭代器时,迭代器依赖于不变的数组快照。
    有数组拷贝的操作,会存在一个问题,数据不一致的问题,如果写线程还没来得及写入内存,其他线程就会读到脏数据。但是在CopyOnWriteList中,保存数据的数组,使用volatile关键字修饰,也就是说,当前数组的修改,会被其他线程立刻读取到。保证了一个线程读取volatile修饰的数组,总能看到其他线程对改数组最后的写入,就这样,通过volatile提供了“读取数据总是最新的”这个机制的保证。

HashSet和HashMap在多线程情况下,不安全

package com.shaonian.juc.list_thread_secure;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author 长名06
 * @version 1.0
 */
public class HashSetDemo {
    public static void main(String[] args) {
        //解决方案,使用CopyOnWriteHashSet
        Set<String> set = new HashSet<>();
        for (int i = 0; i < 30; i++) {
            //会出现java.util.ConcurrentModificationException
            new Thread(() -> {
                set.add(UUID.randomUUID().toString().substring(0, 8));
                System.out.println(set);
            }, String.valueOf(i)).start();
        }
    }
}
package com.shaonian.juc.list_thread_secure;

import java.util.*;

/**
 * @author 长名06
 * @version 1.0
 */
public class HashMapDemo {
    public static void main(String[] args) {
        //解决方案,使用ConcurrentHashMap
        Map<String,String> map = new HashMap<>();
        for (int i = 0; i < 30; i++) {
            String key = String.valueOf(i);
            //会出现java.util.ConcurrentModificationException
            new Thread(() -> {
                map.put(key,UUID.randomUUID().toString().substring(0, 8));
                System.out.println(map);
            }, String.valueOf(i)).start();
        }
    }
}

小结

线程不安全与其对应的安全集合

集合中存在线程存在和线程不安全的例如ArrayList -- Vector HashMap -- HashTable,但是以上都是syncronized关键字实现的。

Collections构建的线程安全集合

通过使用Collections中的synchronizedList()/synchronizedMap(),将不安全的集合,转成线程安全的。

java.util.concurrent包下的

CopyOnWriteList和CopyOnWriteSet类型,通过动态数组与加锁保证线程安全。

只是为了记录自己的学习历程,且本人水平有限,不对之处,请指正。下·文章来源地址https://www.toymoban.com/news/detail-740014.html

到了这里,关于常用集合线程安全分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 为什么arrayList线程不安全?

            ArrayList是Java中的一种动态数组,它在内部使用数组来存储元素。ArrayList的线程不安全性主要体现在多线程并发访问和修改同一个ArrayList实例时可能出现的问题。         当多个线程同时对ArrayList进行修改操作时,可能会导致数据不一致或者出现异常。这是因为

    2024年02月12日
    浏览(53)
  • 【List篇】ArrayList 的线程不安全介绍

    ArrayList 为什么线程不安全? 主要原因是ArrayList是 非同步 的,没有 同步机制 ,并且其底层实现是 基于数组 ,而数组的 长度是固定 的。当对 ArrayList 进行增删操作时,需要改变数组的长度,这就会导致多个线程可能同时操作同一个数组,从而引发线程安全问题。 具体来说,如

    2024年02月03日
    浏览(63)
  • 案例15-ArrayList线程不安全,共用全局变量导致数据错乱问题,占用内存情况

    存入redis的值,可能会出现错误的情况。如果出现错误,接口将会报错。 多个方法一起修改一个 公共变量 的值,造成数据混乱,导致存入redis中的key值错误 还有每次登陆都会重现创建一个对象,放到公共变量中,遇到并发,对象会被大量地创建, 上一个对象会失去引用,等

    2024年02月02日
    浏览(41)
  • 面试官问 : ArrayList 不是线程安全的,为什么 ?(看完这篇,以后反问面试官)

    金三银四 ? 也许,但是。 近日,又收到金三银四一线作战小队成员反馈的战况 : 我不管你从哪里看的面经,但是我不允许你看到我这篇文章之后,还不清楚这个面试问题。 本篇内容预告:   ArrayList 是线程不安全的, 为什么 ? ① 结合代码去探一探所谓的不安全  ② 我们

    2024年02月02日
    浏览(59)
  • 多线程---线程安全的集合类

    我们原先学习过的集合类,大部分都是线程不安全的。只有Vector、Stack、HashTable是线程安全的,但是也不推荐使用。通常情况下,我们都会使用下面介绍的这几种数据结构来保证多线程中的线程安全。 synchronizedList是通过对list的每个操作都加上synchronized来保证线程安全的。

    2024年02月06日
    浏览(29)
  • Java 多线程之线程安全集合

    集合关系图 本文主要关注线程安全的集合,如 List、Set、Queue、Map 等接口的线程安全的实现方式,有关集合基础知识请转到这里。所谓线程安全集合,就是在多线程环境中使用集合不会导致数据不一致和数据异常的集合。在 Java 中线程安全集现在基本都使用 java.util.concurrent

    2024年02月05日
    浏览(48)
  • java基础之线程安全问题以及线程安全集合类

    当多个线程同时访问同一个临界资源时,原子操作可能被破坏,会导致数据丢失, 就会触发线程安全问题 临界资源: 被多个线程同时访问的对象 原子操作: 线程访问临界资源的过程中不可更改和缺失的操作 互斥锁 每个对象都默认拥有互斥锁, 该锁默认不开启. 当开启互斥锁之后

    2024年01月18日
    浏览(54)
  • 线程安全的集合类

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 我会简单的介绍一些线程安全的集合类,还有它们的基本构成,大家请不要安心难度的问题,现在只是简单的了解一下.为什么要涉及线程安全的集合类呢?因为假如说我们要在多线程环境下使用,怎么办?这里

    2023年04月12日
    浏览(20)
  • 安全线程的集合

    方法推荐1.先会用2.货比三家,寻找其他解决方案 3.看源码  CopyOnWriteArrayList 是 Java 中的一个线程安全的集合类,它的设计目的是在读操作非常频繁,而写操作相对较少的情况下提供高效的并发访问。 CopyOnWriteArrayList 使用写入时复制(Copy-On-Write)的机制来实现线程安全。当有

    2024年02月07日
    浏览(20)
  • 面试:线程安全的集合

    线程安全的集合: 线程安全的集合有Vector、HashTable、Stack、ArrayBlockingQueue、ConcurrentHashMap、ConcurrentLinkedQueue等。 1、Vector相当于 ArrayList 的翻版,是长度可变的数组,Vector的每个方法都加了 synchronized 修饰符,是线程安全的。 2、Hashtable是一个线程安全的集合,是单线程集合,它

    2023年04月26日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包