当前位置: 首页 > news >正文

面试官:为什么说ArrayList线程不安全?

本博客知识点收录于:⭐️《JavaSE系列教程》⭐️

1)线程安全与不安全集合

我们学习集合的时候发现集合存在由线程安全集合和线程不安全集合;线程安全效率低,安全性高;反之,线程不安全效率高,安全性低,线程不安全的集合有:Vector,Stack,Hashtable等;

  • 查看Vector和Hashtable等源代码:

在这里插入图片描述

线程安全集合中的方法大部分都加上了synchronized关键字来保证线程的同步;

  • 线程不安全集合:

在这里插入图片描述

2)线程不安全集合测试

  • 数据覆盖问题:
package com.dfbz.demo05;import java.util.ArrayList;/*** @author lscl* @version 1.0* @intro:*/
public class Demo01_集合的线程安全问题 {public static void main(String[] args) throws InterruptedException {ArrayList<String> arr = new ArrayList<>();for (int j = 0; j < 20; ++j) {new Thread(() -> {for (int i = 0; i < 100; i++) {arr.add("1");try {// 然线程安全问题更加突出Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}).start();}}
}

运行代码,发现出现数组下标越界异常:

在这里插入图片描述

分析ArrayList源码:

  • 假设此时size为9,size+1并没有大于数组的默认长度(10),并没有造成数组的扩容,等待代码将集合的9下标赋值后,size++还没来得及运算,CPU的执行权就被其他的线程抢走了,此时size仍旧为9,但此时集合中已经存储了10个元素了;等到其他线程来执行ensureCapacityInternal(9+1)—>ensureCapacityInternal—>ensureExplicitCapacity发现10-10还是小于0,依旧不扩容,代码执行elementData[size++]=e时(还没执行),线程执行权由回到了第一条线程,size++,变为10,然后线程执行器又变回执行elementData[size++]=e这段代码时的那个线程,出现了elementData[10]=e,出现数组下标越界;

在这里插入图片描述

Tips:HashMap同样会出现这个问题,将集合换成Vector或者Stack等线程安全集合可以解决这些问题;或者使用JDK提供的其他线程同步集合也可以解决这些问题;

http://www.lryc.cn/news/26813.html

相关文章:

  • STP详解
  • linux AWK常用命令 —— 筑梦之路
  • SpringCloud:服务拆分及远程调用
  • 网络应用之javascript函数定义和调用
  • 使用VNC远程连接Ubuntu - 内网穿透实现公网远程办公
  • JavaScript Date 日期对象
  • 婴幼儿常见八大疾病及护理方法
  • UVa 817 According to Bartjens 数字表达式 DFS ID 迭代加深搜 逆波兰表达式
  • c++基础/类和对象
  • 2023年中国人工智能产业趋势报告
  • STM32定时器的配置,解析预分频系数和重装载值与时钟频率的关系
  • 解决Sql WorkBench中数据库不能重命名的问题
  • REFL: 联邦学习中智能的设备选择方法
  • Linux:NFS服务器
  • 电子技术——数字逻辑反相器
  • python的多线程编程之锁
  • Android Framework-进程间通信——Binder
  • 有趣的小知识(二)浏览器内的秘密:了解Cookie基础知识
  • Spring框架
  • mysql8的表锁排查
  • 【C语言】深度理解指针(上)
  • 最近我的视频播放浅学总结
  • 【C/C++基础知识点】输出n位斐波那契数列
  • C语言拔高知识——指针的进阶(万字大文超详细)
  • 程序员推荐的良心网站合集!(第二期)
  • 【Java核心知识】spring boot整合Mybatis plus + Phoenix 访问Hbase与使用注意
  • lua实现游戏全局鼠标点击效果
  • MyBatis源码分析(二、续)SqlSource创建流程,SQL如何解析?如何将#{id}变成?的
  • 用 C 语言开发一门编程语言 — 函数库的设计与实现
  • 网络层IP协议与数据链路层以太网协议