JUC---07解决集合线程不安全
一、ArrayList是线程不安全的,可以使用以下操作解决:
1.使用相同功能的集合类替换,比如Vector集合是线程安全的,他们实现的接口都是一样的,但是Vector类是在jdk1.0出现的,不推荐使用
2.使用 java.util.Collections类里面的静态方法synchronizedXXX(xxx),把不安全的集合当参数放进去。
3.使用java.util.concurrent.CopyOnWriteArrayList或java.util.concurrent.CopyOnWriteArraySet
二、从上面第二个知道Map与Set都是线程不安全的,其中Map的第三个解决方法是 java.util.concurrent.ConcurrentHashMap
三、代码实现
- package com.jenne.mydemo;
- import org.junit.jupiter.api.Test;
- import java.util.*;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.CopyOnWriteArrayList;
- import java.util.concurrent.CopyOnWriteArraySet;
- public class TestCollection {
- @Test
- public void testList() {
- /* //可能会出现java.util.ConcurrentModificationException
- List<String> list = new ArrayList<>();
- for (int i = 1; i <= 8; i++) {
- new Thread(() -> {
- list.add(Thread.currentThread().getName()+"--->测试");
- System.out.println(list);
- }).start();
- }*/
- /*List<String> list = new Vector<>();//不推荐
- for (int i = 1; i <= 6; i++) {
- new Thread(() -> {
- list.add(Thread.currentThread().getName()+"--->测试");
- System.out.println(list);
- }).start();
- }*/
- /*List<String> list = Collections.synchronizedList(new ArrayList<>());//不推荐
- for (int i = 1; i <= 6; i++) {
- new Thread(() -> {
- list.add(Thread.currentThread().getName()+"--->测试");
- System.out.println(list);
- }).start();
- }*/
- List<String> list = new CopyOnWriteArrayList<>();//推荐使用
- for (int i = 1; i <= 6; i++) {
- new Thread(() -> {
- list.add(Thread.currentThread().getName() + "--->测试");
- System.out.println(list);
- }).start();
- }
- }
- @Test
- public void testSet() {
- /*//java.util.ConcurrentModificationException
- Set<String> set = new HashSet<>();
- for (int i = 1; i <= 16; i++) {
- new Thread(() -> {
- set.add(Thread.currentThread().getName()+"--->测试");
- System.out.println(set);
- }).start();
- }*/
- /* Set<String> set = Collections.synchronizedSet(new HashSet<>());//不推荐
- for (int i = 1; i <= 16; i++) {
- new Thread(() -> {
- set.add(Thread.currentThread().getName()+"--->测试");
- System.out.println(set);
- }).start();
- }*/
- Set<String> set = new CopyOnWriteArraySet<>();//推荐使用
- for (int i = 1; i <= 16; i++) {
- new Thread(() -> {
- set.add(Thread.currentThread().getName() + "--->测试");
- System.out.println(set);
- }).start();
- }
- }
- @Test
- public void testMap() {
- /*//java.util.ConcurrentModificationException
- Map<String,String> map = new HashMap<>();
- for (int i = 1; i <= 16; i++) {
- new Thread(() -> {
- map.put(Thread.currentThread().getName(),"--->测试");
- System.out.println(map);
- }).start();
- }*/
- /*Map<String, String> map = Collections.synchronizedMap(new HashMap<>());//不推荐
- for (int i = 1; i <= 16; i++) {
- new Thread(() -> {
- map.put(Thread.currentThread().getName(), "--->测试");
- System.out.println(map);
- }).start();
- }*/
- Map<String,String> map = new ConcurrentHashMap<>();//推荐使用
- for (int i = 1; i <= 16; i++) {
- new Thread(() -> {
- map.put(Thread.currentThread().getName(),"--->测试");
- System.out.println(map);
- }).start();
- }
- }
- }
JUC---07解决集合线程不安全的更多相关文章
- 解决ArrayList线程不安全
前些天做项目时,程序出现意外的问题,经后来分析是使用ArrayList这个线程不安全的方法导致 解决这个问题通常有两种方法(个人认为) 一:使用synchronized关键字,这个大家应该都很熟悉了, ...
- android 解决子线程进行UI操作
Android确实不允许在子线程中进行UI操作的,但我们有时必须在子线程里去执行一些耗时的任务,然后根据任务的执行结果来更新相应的UI控件. Android提供了一套异步消息处理机制,可以解决子线程中 ...
- JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor
JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor.它主要用来在 ...
- JUC源码分析-线程池篇(二)FutureTask
JUC源码分析-线程池篇(二)FutureTask JDK5 之后提供了 Callable 和 Future 接口,通过它们就可以在任务执行完毕之后得到任务的执行结果.本文从源代码角度分析下具体的实现 ...
- JUC源码分析-线程池篇(三)Timer
JUC源码分析-线程池篇(三)Timer Timer 是 java.util 包提供的一个定时任务调度器,在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次. 1. Ti ...
- JUC源码分析-线程池篇(一):ThreadPoolExecutor
JUC源码分析-线程池篇(一):ThreadPoolExecutor Java 中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池 ...
- Java 集合 线程安全
Java中常用的集合框架中的实现类HashSet.TreeSet.ArrayList.ArrayDeque.LinkedList.HashMap.TreeMap都是线程不安全的,如果多个线程同时访问它 ...
- List 集合线程安全测试
最近在做一些代码整理工作,涉及到List 线程安全问题,查了一些资料.网上有些资料说List 增减成员(Add , Remove) 是安全的,但不保证成员属性值访问安全性,及禁止对 List 跨线程遍 ...
- 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析
看两个例子,一个是在一个进程里设置另外一个进程中控件的属性.另外一个是在一个进程里获取另外一个进程中控件的属性. 第一个例子 最近,在做一个使用线程控制下载文件的小程序(使用进度条控件显示下载进度)时 ...
随机推荐
- django中外键的related_name属性
我先定义两个模型,一个是作者,一个是作者出版的书籍,算是一对多的类型. class Person(models.Model); name = models.CharField(verbose_name ...
- 每日爬虫JS小逆之5分钟旅游网MD5一锅端
来吧骚年,每天花5分钟锻炼一下自己的JS调试也是极好的,对后期调试滑块验证码还原.拖动很有帮助,坚持下去,我们能赢.建议亲自试试哦,如果对大家有帮助的话不妨关注一下知识图谱与大数据公众号,当然不关注也 ...
- Java单播、组播(多播)、广播的简单实现
简介 单播有TCP和UDP两种实现,组播(多播)和广播只有UDP一种实现.单播和广播基本一样,只是广播的数据包IP为广播IP. 单播 DatagramSocket和DatagramPacket 服 ...
- Python-全局解释器锁GIL原理和多线程产生原因与原理-多线程通信机制
GIL 全局解释器锁,这个锁是个粗粒度的锁,解释器层面上的锁,为了保证线程安全,同一时刻只允许一个线程执行,但这个锁并不能保存线程安全,因为GIL会释放掉的并且切换到另外一个线程上,不会完全占用,依据 ...
- Oracle 11G RAC11.2.0.4 + Redhat7.3安装手册
安装思路: 1.安装两台redhat7 linux系统 2.网络配置(双网卡,public,vip,private,scan) 3.存储配置(内存配置,ASM共享存储:6块5G共享盘udev,根目录留 ...
- 2020HC大会上,这群人在讨论云原生…
启程 一年一度的华为全联接大会又开启了,伴随着一封来自华为全联接大会的邀请函,我来到了2020华为全联接大会的现场. 理解 今年,华为全联接大会的主题是:共 创 行 业 新 价 值!(NEW VALU ...
- HTML中css水平居中的几种方式
1. 子元素为行内元素时,父元素使用 text-align: center; 实现子元素的水平居中: 2. 子元素为块级元素时, 2.1. 将子元素设置 margin: 0 auto; 实现居中: 2 ...
- 049 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 11 break语句
049 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 11 break语句 本文知识点:break语句 break语句 break语句前情回顾 1.swi ...
- matlab进行FIR滤波器设计(一)
来源:https://blog.csdn.net/leokingszx/article/details/80041910 在实际的应用中,有时需要使用FIR根据完成一些特定功能,比如近似一阶RC低通电 ...
- JProfiler 教程 使用说明
JProfiler (本文原创转载请注明) 简介 JProfiler是一个重量级的JVM监控工具,提供对JVM精确监控,其中堆遍历.CPU剖析.线程剖析看成定位当前系统瓶颈的得力工具.可以统计压 ...