并发问题

一、并发并行

代码线程安全也就意味着多线程场景下的安全问题
多线程下存在并发,并行两种
并发场景下才会产生线程安全问题
并发就是指多线程操作同一资源
并行是指资源互不干涉
这里同一资源操作是指对同一物理地址上的数据
从而导致幻读,脏读等破坏

get这种获取资源的方式是不建议的
get方法直接暴露了物理地址
类中变量如果是基本类型数据,不会有危险
但是这里是引用类型数据
那么每个线程实质上是对同一地址进行了访问
这也就会产生一个问题
A线程获取数组之后往数组里面添加了10条数据
B线程获取数组之后全部删掉
那么A线程读到的数据会被干扰

这里就需要了解JVM内部存储的方式了
这里大家要牢记
网上一些基础知识介绍的并不专业
例如:基本类型数据存在栈上,引用类型数据都在堆上
这个是错误的
正确的是这样的:栈上存放的数据都是和指令顺序相关的数据
总结为:凡是方法内部的基本类型句柄包括数据,全部存储到栈中
凡是对象中的基本类型数据,全部存储在堆中
静态基本类型数据在方法区
引用类型是这样的:凡是方法中的变量句柄全部在栈中
凡是对象域成员的句柄全部存在堆中
静态的在方法区
每NEW一个引用类型对象,都会在堆中申请空间,空间大小由以下几个因素决定的:类信息地址,基本类型变量句柄大小,基本类型数据,引用类型句柄大小,引用类型的指针地址
这个引用类型是指对象内部的引用类型域
对象内部引用类型的真实数据是存在堆的其他地方的,每一个对象地址空间都不包含内部引用成员变量的真实数据
基于此特征,我们代码不小心就可能造成这样的后果:多线程操作同一个地址
所以这里的优化方案是,

  • 第一,使用线程安全的数组类集合
  • 第二,get方法重新new一个新的对象,采用深复制方式将arr数据拷贝过来,最后return new出来的新对象
    这样每个线程在调用的时候都是拿到的new出来的新地址,相互之间并不一样
    从而使得这个类变成线程安全的类
    也就意味着我们get方法针对引用类型域成员变量的时候,要慎重,千万不要轻易在多线程下这样定义
  • 第三就是同学们比较熟悉的加锁了

但是加锁可不管用
这种访问加锁也没有意义
加锁只是保障了同一时刻只有一个线程访问
阻止不了其他线程的修改

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值