Java并发编程之支持并发的list集合你知道吗
Java并发编程之-list集合的并发.
我们都知道Java集合类中的arrayList是线程不安全的。那么怎么证明是线程不安全的呢?怎么解决在并发环境下使用安全的list集合类呢?
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《并发集合系列》教程的第一篇:
本文主要内容:怎么证明arrayList不是线程安全的?怎么解决这个问题?以及遇到问题解决的四个步骤及从源码来分析作者思路。
一:怎么证明arrayList在并发情况下是线程不安全的呢?
创建一个list,用多个线程向list中添加数据。来看看结果
查看运行结果:
我们发现了一个异常:java.util.ConcurrentModificationException
java.util.ConcurrentModificationException是什么
这个异常什么意思呢?我们来看看这个异常源码中类的注释信息:
This exception may be thrown by methods that have detected concurrent(此异常可能由检测到并发的方法引发).
一般可以理解为,这是并发导致的异常。那么在并发情况下出现了异常。是不是从侧面说明arrayList是不安全的呢?
二:怎么解决这个问题
这里凯哥顺便说下,解决问题的一般步骤。
1:怎么操作导致的故障及现象是什么?
操作:多个线程对list进行add添加操作的时候
结果:抛出了java.util.ConcurrentModificationException异常信息
2:分析产生这个问题的原因
举个现实生活中的例子。签到表,这个大家都见过吧,应该都签到过吧。比如现在有个会议很多人来参与,需要签到。现在,司小司正在签到表上写自己的名字时候,小明非要看签到表上面有没有自己名字。因为司小司正在签到进行中,小明硬是要查看,把签到表抢过去,结果就是签到表被撕坏了或者是司小司的笔在签到表上留下了长长的痕迹。如果上面这个例子用计算机角度分析的话。
两个线程(司小司和小明)对一个共享变量(签到表,可以理解为是人名的集合)进行读写操作(司小司签到是写操作,小明要查看自己是否签到了,可以理解为读操作),因为两个线程都来竞争共享资源。后果就是签到表被撕坏了或者是司小司的笔在签到表上留下了长长的痕迹。异常现象。用到上面我们多个线程对list进行操作的时候,就抛异常了多线程并发修改异常信息。
3:解决方案是什么?
1:使用线程安全的List的子类Vectory
List list = new Vectory();
查看vectory的add方法源码:
发现,原来vector的add方法是加的并发锁来保证线程安全的
2:使用collections工具类的sync方法
List list = Colletcions.synchronizedList(new ArrayList<>());
查看源码:
原来都是synchronized的。
我们在来看看synchronizedList方法上面的注释。
发现,原来源码中是把整个list对象作为同步锁的锁。这样来保证线程安全的
4:解决方案可以优化吗?优化的建议是什么?
我们知道synchronized关键字是同步锁机制。强制并行转化成串行的一种方案。这种对性能消耗比较大。有没有更其他可以优化的方案吗?
来看看使用JUC并发包下的:CopyOnWriteArrayList(写时复制list)来解决吧。
先来看看这个类的add方法的源码:
从源码中,我们可以看到复制了一个新的list集合,将新元素在新集合中操作。那么为什么这种操作就不会出现并发异常呢?
因为这种思想,可以理解为读写分离的思想。因为get还是使用原来list的get的方法。写的时候,在复制一份原来的,然后再复制出来的基础上进行修改的。那么怎么保证数据问题呢?我们从源码中可以看到使用到了ReentrantLock(关于锁相关的。凯哥(凯哥Java:kaigejava)将在后面详细的讲解的)锁来控制的。
那么现在使用CopyOnWriteArrayList来模拟下文章开头签到例子。
司小司再签到的时候,先把签到表复制一份,然后再新的复制出来的签到表中进行签到。小明是原来签到表查看自己的信息的。这样就不会出现争强情况了。

Java并发编程之支持并发的list集合你知道吗的更多相关文章
- java并发编程--第一章并发编程的挑战
一.java并发编程的挑战 并发编程需要注意的问题: 并发编程的目的是让程序运行的更快,然而并不是启动更多的线程就能让程序最大限度的并发执行.若希望通过多线程并发让程序执行的更快,会受到如下问题的挑战 ...
- java并发编程与高并发解决方案
下面是我对java并发编程与高并发解决方案的学习总结: 1.并发编程的基础 2.线程安全—可见性和有序性 3.线程安全—原子性 4.安全发布对象—单例模式 5.不可变对象 6.线程封闭 7.线程不安全 ...
- Java并发编程系列-(1) 并发编程基础
1.并发编程基础 1.1 基本概念 CPU核心与线程数关系 Java中通过多线程的手段来实现并发,对于单处理器机器上来讲,宏观上的多线程并行执行是通过CPU的调度来实现的,微观上CPU在某个时刻只会运 ...
- 并发编程概述--C#并发编程经典实例
优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版.NET 中的程序库和语 ...
- 【并发编程】Java对并发编程的支持历史
本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 本文转载,原文请点击链接 本章主要对Java并发(Con ...
- 【Java并发编程】:并发新特性—Executor框架与线程池
Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocur ...
- Java并发编程实战笔记—— 并发编程1
1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...
- Java并发编程实战 01并发编程的Bug源头
摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 ...
- 【Java并发编程】:并发新特性—障碍器CyclicBarrier
CyclicBarrier(又叫障碍器)同样是Java5中加入的新特性,使用时需要导入Java.util.concurrent.CylicBarrier.它适用于这样一种情况:你希望创建一组任务,它们 ...
随机推荐
- Python不使用元类创建缓存实例
问题 当创建类实例时我们想返回一个缓存引用,让其指向上一个用同样参数(如果有的话)创建出来的类实例. 这个问题常常出现在当我们想确保针对一组输入参数只会有一个类实例存在时. 解决方法: 使用一个与类本 ...
- 环境安装文档(for Ubuntu)
这个文档的目标是:各位小伙伴通过这个文档,可以在一台全新的 Ubuntu 电脑上搭建平常开发使用的环境,主要包含 Node.js, git 和 编辑器部分. 这是针对 Ubuntu 系统的安装文档,W ...
- C2C的道德边界:沦为从假运单到假病条的供假渠道
你可能刚开始学会不去看网购平台上商品回评中的虚假好评,却又要开始应对同事在朋友圈等平台买来的虚开病假条带来的困扰.最近各大媒体包括党报热传的网购病假条事件,再度将人们的目光集中在这个C2C模式之上.从 ...
- SDWebImage -- 封装 (网络状态检测,是否打开手机网络下下载高清图设置)
对SDWebImage 进行封装,为了更好的节省用户手机流量,并保证在移动网络下也展示高清图,对使用SDWebImage 下载图片之前进行逻辑处理,根据本地缓存中是否有缓存原始的图片,用户是否打开移动 ...
- jquery-购物车js
购物车示例js,为了方便参考,页面写的比较简单.示例如下图所示: html代码如下: <!doctype html> <html lang="en"> &l ...
- php表单提交后再后退 内容则默认清空的解决方法
转载原文地址: http://www.jquerycn.cn/a_14422 在session_start()之后,字符输出之前加上header("Cache-control: privat ...
- JZOJ 5236. 【NOIP2017模拟8.7A组】利普希茨
5236. [NOIP2017模拟8.7A组]利普希茨 (File IO): input:lipschitz.in output:lipschitz.out Time Limits: 1000 ms ...
- redis 出现(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details
如果在ubuntu安装的redis含端口使用,但是某些时候常常出现 (error) MISCONF Redis is configured to save RDB snapshots, but is ...
- 项目测试中发现产品bug怎么办
我所在的产品线,并非公司最大最强的产品 甚至为了推广我们这个产品,一般会拿给客户先免费试用 而在试用之前,是要经过一番通测的,测得很急,测得很快 所以产品bug非常多 那么在测试项目的时候,自然会发现 ...
- ubuntu16.04 + caffe + SSD + gpu 安装
昨天我们买好了硬件,今天我们开始安装caffe了,我本人安装过caffe不下10次,每次都是一大堆问题,后来终于总结了关键要点,就是操作系统. 1. 千万不要用ubuntu17.10来安装, 2. 最 ...