一、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解决集合线程不安全的更多相关文章

  1. 解决ArrayList线程不安全

    前些天做项目时,程序出现意外的问题,经后来分析是使用ArrayList这个线程不安全的方法导致 解决这个问题通常有两种方法(个人认为) 一:使用synchronized关键字,这个大家应该都很熟悉了, ...

  2. android 解决子线程进行UI操作

    Android确实不允许在子线程中进行UI操作的,但我们有时必须在子线程里去执行一些耗时的任务,然后根据任务的执行结果来更新相应的UI控件. Android提供了一套异步消息处理机制,可以解决子线程中 ...

  3. JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor

    JUC源码分析-线程池篇(三)ScheduledThreadPoolExecutor ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor.它主要用来在 ...

  4. JUC源码分析-线程池篇(二)FutureTask

    JUC源码分析-线程池篇(二)FutureTask JDK5 之后提供了 Callable 和 Future 接口,通过它们就可以在任务执行完毕之后得到任务的执行结果.本文从源代码角度分析下具体的实现 ...

  5. JUC源码分析-线程池篇(三)Timer

    JUC源码分析-线程池篇(三)Timer Timer 是 java.util 包提供的一个定时任务调度器,在主线程之外起一个单独的线程执行指定的计划任务,可以指定执行一次或者反复执行多次. 1. Ti ...

  6. JUC源码分析-线程池篇(一):ThreadPoolExecutor

    JUC源码分析-线程池篇(一):ThreadPoolExecutor Java 中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序都可以使用线程池.在开发过程中,合理地使用线程池 ...

  7. Java 集合 线程安全

    Java中常用的集合框架中的实现类HashSet.TreeSet.ArrayList.ArrayDeque.LinkedList.HashMap.TreeMap都是线程不安全的,如果多个线程同时访问它 ...

  8. List 集合线程安全测试

    最近在做一些代码整理工作,涉及到List 线程安全问题,查了一些资料.网上有些资料说List 增减成员(Add , Remove) 是安全的,但不保证成员属性值访问安全性,及禁止对 List 跨线程遍 ...

  9. 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析

    看两个例子,一个是在一个进程里设置另外一个进程中控件的属性.另外一个是在一个进程里获取另外一个进程中控件的属性. 第一个例子 最近,在做一个使用线程控制下载文件的小程序(使用进度条控件显示下载进度)时 ...

随机推荐

  1. 轻轻松松学CSS:overflow

    一.overflow的定义 overflow,音[əʊvəˈfləʊ],义[溢出],就像2.2米的人躺在1.8米的床上,腿得耷拉到床外一样.overflow 属性用于控制内容溢出容器时显示的方式 二. ...

  2. Linux服务器内存监控—每小时检查&超出发送邮件&重启占用最高的Java程式

    简介与优点 使用该脚本能自行判断系统内存使用情况是否超出设定百分比 能在超出预警值时执行重启程式的操作 能记录重启过程,并将具体LOG邮件发送给指定收信人 可以设定Crontab排程,达成每隔一段时间 ...

  3. ubuntu下一键安装pptpd

    1 #!/bin/bash 2 # Quick and dirty pptp VPN install script 3 # Ubuntu 12+ or Debain 7+ 4 # Reference ...

  4. Spring Boot 第三弹,一文带你了解日志如何配置?

    前言 日志通常不会在需求阶段作为一个功能单独提出来,也不会在产品方案中看到它的细节.但是,这丝毫不影响它在任何一个系统中的重要的地位. 今天就来介绍一下Spring Boot中的日志如何配置. Spr ...

  5. Spring 配置文件AOP

    1 <!-- 配置切面bean --> 2 <bean id="permAspect" class="com.tx.spring.aspect.Perm ...

  6. Python-读写csv数据模块 csv

    案例: 通过股票网站,我们获取了中国股市数据集,它以csv数据格式存储 Data,Open,High,Low,Close,Volume,Adj Close 2016-06-28,8.63,8.47,8 ...

  7. 理解pytorch几个高级选择函数(如gather)

    目录 1. 引言 2. 维度的理解 3. gather函数 4. index_select函数 5. masked_select函数 6. nonzero函数 1. 引言   最近在刷开源的Pytor ...

  8. 温故知新——C++--封装

      参考: 1.https://blog.csdn.net/cherrydreamsover/article/details/81942293 2.https://www.cnblogs.com/ji ...

  9. 【题解】CF1368C Even Picture

    \(\color{purple}{Link}\) \(\text{Solution:}\) 这是一道构造题. 题目要求恰好有\(n\)个点的四周全都是灰色点,所以直接输正方形是不行了. 考虑\(k=1 ...

  10. ASP。NET Core路到微服务第01部分:构建视图

    下载Part 1 source - 2.9 MB 介绍 说,如果你觉得有点失望找不到任何实际microservices在这篇文章中,这是因为有很多科目我想盖,它不可能谈论他们所有人(或讨论的多)在一篇 ...