资讯专栏INFORMATION COLUMN

ArrayList 线程安全性学习

genedna / 2879人阅读

摘要:线程安全吗虽然天天用,但是真的没考虑过这个问题。其实,线程不安全。没有对多线程问题进行处理,举个方法的例子就能证明它线程不安全。线程不安全的要比线程安全的执行效率高。

引言

最近学校的氛围比较活跃,考研的复习,不考研的都在写简历准备面试。

看了看,最近也没有好公司来办宣讲会,也就没了投简历的意向。最近看了看面试题,想着补一补基础,以后面几家Spring Cloud的企业,去和面试官交流交流。

Spring Cloud的学习与体会

最近看了《Spring Cloud微服务实战》一书,感觉受益匪浅,大有裨益。

高并发应用,必须是要启用Spring Cloud的。有了Spring Cloud,就不用再像之前一样,前端工程师团队,后端工程师团队,运维团队。而是按模块划分,订单模块团队,支付模块团队,每个团队里都是从前端到后台到运维的全栈工程师。

就像上次黄庭祥说的,ThinkPHP开发,他写学期管理;AngularJS开发,他又写学期管理;Angular开发,他还写学期管理。想到什么了么?肯定精通这个模块的业务逻辑啊?

如果培养出优秀的支付模块团队、优秀的安全模块团队、优秀的高并发优化团队,其实淘宝也不过如此。

相互的依赖,从原来的@Autowired转为服务器接口间的调用。每个模块都是一个Spring Cloud应用,各应用间通过互相调用、相互协作共同实现业务功能,同时,各应用模块可以采用不同的数据库,以发挥各数据库之所长。

然后后台分布式部署,到了并发的时候,给相应的模块加服务器负载均衡就是了。个人中心模块,不常用,两个服务器负载;订单模块,可能会并发,加个百十来个服务器负载均衡。当然,像618、双十一这样的场景,肯定不是加服务器就能解决的,我这里只是举个简单的例子。模块划分之后,可以有针对性地解决高并发问题。

不扯淡了,开始进入正题。

面试题 再谈线程安全

什么是线程安全?

我看到这道题就感觉怎么也说不出来,就是多线程的环境下运行,我这个应用也不炸,虽然是这个意思,但是也不能这样回答啊?一时之间,找不到相关的学术词汇回答此问题。

这是想了许久后,我自己总结出的回答:

程序在单线程环境下正常执行得到了正确的结果,在多个线程并发执行的环境条件下,仍然能得到像单线程一样正确的结果,这就是线程安全。

如果一个类(或对象),我们在使用时,无需考虑任何多线程相关的问题,就像单线程一样使用,且最后能得到正确的结果,那就说这个类(或对象)是线程安全的。

ArrayList线程安全吗?

看了许多面试题,发现面试官都喜欢以一个小方面进行切入,然后无限扩展,直到把面试者问懵圈为止。

ArrayList线程安全吗?

虽然天天用ArrayList,但是真的没考虑过这个问题。其实,ArrayList线程不安全。

ArrayList是一个内部采用数组实现的线性表,它相比数组最大的优点就是使用时可以不用去像数组一样new的时候去考虑要容纳多少个元素。ArrayList默认构造一个容量为10的数组。

private static final int DEFAULT_CAPACITY = 10;

如果容量不够了,ArrayList会自动扩容,扩容至原来的1.5倍。(右移一位,相当于除以2)。

int newCapacity = oldCapacity + (oldCapacity >> 1);

ArrayList没有对多线程问题进行处理,举个add方法的例子就能证明它线程不安全。

elementData[size++] = e;

别看这是一行,其实是执行了两步操作,赋值和自增。

线程A add一个元素,然后暂停执行,size还没自增,然后线程Badd元素,size没变,就直接把A add的元素覆盖了。

不安全为什么要使用?

又回到了之前向晨澍请教的问题,线程安全,必然是有额外开销的。

所以List的三个接口ArrayListLinkedListVector

线程不安全的要比线程安全的执行效率高。所以我们常用的是线程不安全的ArrayListLinkedList,而从来没有用过线程安全的Vector

VectorJDK1.0就存在,设计得不够完善,多线程情况下如果使用不当也会发生错误,不推荐使用。

如何解决线程不安全

既然Vector不能用,那我就想要一个线程安全的List得怎么整呢?

调用Collections.synchronizedList方法,使ArrayList线程安全。

List synchronizedList = Collections.synchronizedList(new ArrayList<>());

返回SynchronizedList类的对象,经典的装饰器模式,对方法访问加了同步。

public void add(int index, E element) {
    synchronized (mutex) {list.add(index, element);}
}
public E remove(int index) {
    synchronized (mutex) {return list.remove(index);}
}
总结
何处望神州?满眼风光北固楼。千古兴亡多少事?悠悠。不尽长江滚滚流。

年少万兜鍪,坐断东南战未休。天下英雄谁敌手?曹刘。生子当如孙仲谋。

——辛弃疾 《南乡子·登京口北固亭有怀》

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/74497.html

相关文章

  • Java 常用List集合使用场景分析

    摘要:常用集合使用场景分析过年前的最后一篇,本章通过介绍,,,底层实现原理和四个集合的区别。和都是线程安全的,不同的是前者使用类,后者使用关键字。面试官会认为你是一个基础扎实,内功深厚的人才到这里常用集合使用场景分析就结束了。 Java 常用List集合使用场景分析 过年前的最后一篇,本章通过介绍ArrayList,LinkedList,Vector,CopyOnWriteArrayList...

    godruoyi 评论0 收藏0
  • 出场率比较高的一道多线程安全面试题

    摘要:程序正常运行,输出了预期容量的大小这是正常运行结果,未发生多线程安全问题,但这是不确定性的,不是每次都会达到正常预期的。另外,像等都有类似多线程安全问题,在多线程并发环境下避免使用这种集合。 这个问题是 Java 程序员面试经常会遇到的吧。 工作一两年的应该都知道 ArrayList 是线程不安全的,要使用线程安全的就使用 Vector,这也是各种 Java 面试宝典里面所提及的,可能...

    xiyang 评论0 收藏0
  • [Java并发-11] 并发容器的使用

    摘要:同步容器及其注意事项中的容器主要可以分为四个大类,分别是和,但并不是所有的容器都是线程安全的。并发容器及其注意事项在版本之前所谓的线程安全的容器,主要指的就是同步容器,当然因为所有方法都用来保证互斥,串行度太高了,性能太差了。 Java 并发包有很大一部分内容都是关于并发容器的,因此学习和搞懂这部分的内容很有必要。 Java 1.5 之前提供的同步容器虽然也能保证线程安全,但是性能很差...

    legendaryedu 评论0 收藏0
  • java学习(七) —— API集合类

    摘要:集合类主要负责保存盛装其他数据,因此集合类也被称为容器类。所有的集合类都位于包下。表示一组对象,这些对象也称为的元素。成员方法把集合转成数组迭代器,集合的专用遍历方式之接口概述有序的,也称为序列。 前言 在编程中,常常需要集中存放多个数据。从传统意义上讲,数组是我们的一个很好的选择,前提是我们实现已经明确知道我们将要保存的对象的数量。 一旦在数组初始化时指定了数组长度,这个数组长度就...

    senntyou 评论0 收藏0
  • Java--☀️面试官:LinkedList真的比ArrayList添加元素快?❤️‍本文通过Ope

    欢迎进来学习的小伙伴,本文将会带你揭开真相~ 【学习背景】 不管你是学生,还是职场小白,还是入行Java几年的小伙伴,相信很多小伙伴在面试Java工作岗位时,发现LinkedList和ArrayList这两者相关的问题基本是必面的~ 但是当面试官问到LinkedList和ArrayList的区别时,可能很多准备得不够充分的小伙伴第一反应给出的回答仅仅是这样的: LinkedList底层数据结...

    greatwhole 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<