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集合你知道吗的更多相关文章

  1. java并发编程--第一章并发编程的挑战

    一.java并发编程的挑战 并发编程需要注意的问题: 并发编程的目的是让程序运行的更快,然而并不是启动更多的线程就能让程序最大限度的并发执行.若希望通过多线程并发让程序执行的更快,会受到如下问题的挑战 ...

  2. java并发编程与高并发解决方案

    下面是我对java并发编程与高并发解决方案的学习总结: 1.并发编程的基础 2.线程安全—可见性和有序性 3.线程安全—原子性 4.安全发布对象—单例模式 5.不可变对象 6.线程封闭 7.线程不安全 ...

  3. Java并发编程系列-(1) 并发编程基础

    1.并发编程基础 1.1 基本概念 CPU核心与线程数关系 Java中通过多线程的手段来实现并发,对于单处理器机器上来讲,宏观上的多线程并行执行是通过CPU的调度来实现的,微观上CPU在某个时刻只会运 ...

  4. 并发编程概述--C#并发编程经典实例

    优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版.NET 中的程序库和语 ...

  5. 【并发编程】Java对并发编程的支持历史

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 本文转载,原文请点击链接 本章主要对Java并发(Con ...

  6. 【Java并发编程】:并发新特性—Executor框架与线程池

    Executor框架简介 在Java5之后,并发编程引入了一堆新的启动.调度和管理线程的API.Executor框架便是Java 5中引入的,其内部使用了线程池机制,它在java.util.cocur ...

  7. Java并发编程实战笔记—— 并发编程1

    1.如何创建并运行java线程 创建一个线程可以继承java的Thread类,或者实现Runnabe接口. public class thread { static class MyThread1 e ...

  8. Java并发编程实战 01并发编程的Bug源头

    摘要 编写正确的并发程序对我来说是一件极其困难的事情,由于知识不足,只知道synchronized这个修饰符进行同步. 本文为学习极客时间:Java并发编程实战 01的总结,文章取图也是来自于该文章 ...

  9. 【Java并发编程】:并发新特性—障碍器CyclicBarrier

    CyclicBarrier(又叫障碍器)同样是Java5中加入的新特性,使用时需要导入Java.util.concurrent.CylicBarrier.它适用于这样一种情况:你希望创建一组任务,它们 ...

随机推荐

  1. 【深圳·招聘】QQ音乐测试工程师-职位内推

    QQ音乐测试工程师 岗位职责 负责腾讯QQ音乐移动端/后台/web相关特性测试分析和执行,保障发布质量. 岗位要求 专业本科及以上学历,计算机/软件工程/信息管理/数学与应用数学/自动化/通信工程/电 ...

  2. Spring Boot框架开发的Java项目在CentOS7上的部署

    需求:上级拿来一份Spring Boot框架开发的Java项目代码让我在服务器上运行起来,只说了一句该框架是自带了Tomcat(不用重新安装Tomcat),一份代码下有两个项目(一个管理端项目,一个用 ...

  3. 关于Linux文件系统

    前言 文件系统是在内核中实现,能够对存储在磁盘上的二进制数据进行有效的层次化管理的一种软件.而用户程序为了实现在磁盘上使用或者创建文件,向内核发起系统调用(实际由文件系统向内核发起的系统调用)并转换为 ...

  4. 《SDN期末作业——实现负载均衡》

    队名:取个队名真难 一.网络拓扑(场景二) 二.负载均衡程序 1.建立拓扑的代码 拓扑 2.下发组表流表的代码 下发组表流表 三.演示视频 1.目的 服务器h2,h3,h4上各自有不同的服务,h1是客 ...

  5. 达拉草201771010105《面向对象程序设计(java)》第八周学习总结

    达拉草201771010105<面向对象程序设计(java)>第八周学习总结 实验六接口的定义与使用 实验时间 2018-10-18 1.实验目的与要求 (1) 掌握接口定义方法: (2) ...

  6. 大多数项目中会用到的webpack小技巧

    原文地址 本文是作者对自己所学的webpack技巧的总结,在没有指定特殊情况下适用于webpack 3.0版本. 进度汇报 使用webpack --progress --colors这样可以让编译的输 ...

  7. 利用 Rize 来进行 UI 测试或 E2E 测试

    之前我曾经在<Rize - 一个可以让你简单.优雅地使用 puppeteer 的 Node.js 库>一文简单介绍过 Rize 这个库.当时仅仅是介绍这个库本身,关于如何使用,我没有给太多 ...

  8. 搭建Flutter开发环境需要注意的几个小Tips

    目录 下载SDK 安装 Android Stdio + SDK + tool SDK + 创建模拟器 + 插件(flutter和dart) Xcode + cocoapods VSCode + Flu ...

  9. axios下载文件乱码问题 无法解压 文件损坏

    /* 下载附件 */ downloadFile(fileName) { // window.open(url); var that = this; var url = "PO2116&quo ...

  10. API服务版本控制 Microsoft.AspNetCore.Mvc.Versioning

    我们在进行webapi服务开发时,会遇到一些多个版本的api共存的情况发生,例如某一版本APP上线后,需求发生变更,需要在下一个升级版本更新API,但同时又需要保证这个APP版本能正常使用,这时候就需 ...