多线程

JMM(Java内存模型)区别于JVM

volatile相关

内存可见性问题:该问题是指当多个线程操作共享数据时,彼此不可见,都是在自己线程所分配的缓存中修改的
volatile能保证内存可见性,不能保证原子性。因此将共享数据定义成AtomicInteger类型比较合适。这种类型的共享数据通过volatile保证了内存可见性又通过CAS算法保证了原子性。通过CAS算法保证原子性时有两步,第一步是获取内存中的数据,第二步是原子性的,在修改之前再次获取内存中值,然后比较并替换。
CAS算法比加锁效率高的原因是修改不成功后,会不停再次比较,没有加锁时上下文切换导致的消耗,因此效率高,现在在JDK1.8后,concurrentHashMap也摒弃了之前分段锁的机制,采用了CAS算法。


保证内存可见性手段(即主内存和工作内存间的交互操作):
read(读取):从主内存中读取数据
load(载入):将主内存读取到的数据写入工作内存
use(使用):从工作内存读取数据来计算
assign(赋值):将计算好的值重新赋值到工作内存中
store(存储):将工作内存数据写入主内存
write(写入):将store过去的变量赋值给主内存中的变量
lock(锁定):将主内存变量加锁,标识为线程独占状态
unlock(解锁):将主内存变量解锁,解锁后其他线程可以锁定该变量
在这里插入图片描述
如果变量用volatile修饰了,就会在assign操作后,触发后面的store和write(即内存回写),并在回写之前,调用lock操作,将对应内存区域锁住,写完unlock。


保证内存可见性底层实现: 底层是通过缓存一致性协议和总线嗅探机制实现。一个线程在修改共享变量后,会立即将新值写回主内存。这个写回内存的操作会引起其他CPU里缓存了该内存地址的数据无效。这是因为在写回主内存过程中,数据会经过总线,其他CPU启用了总线嗅探机制,监听总线中数据的变化,若存在数据变化,立马让其他线程工作区中的共享数据失效,之后,需要再次获取新数据,这样确保了数据的一致性。
在这里插入图片描述


指令重排序规则:(as-if-serial语义happens-before原则
在这里插入图片描述


单例模式双重检测锁(存在问题,需要解决)
在这里插入图片描述init:对对象的成员变量进行真正的赋值和调用构造方法,对象初始化完成
pubstatic:对静态变量赋值,把对象(即instance实例)赋值给静态变量
总结:上面两步操作被重排序之后,某一线程在给静态变量赋值之后,但是对象的初始化的方法还没有完成,这导致其他线程在判断对象是否为空时,判断不为空,因此可以拿到instance,但此时拿到的是一个半初始的对象


禁止指令重排原理:
内存屏障实现:JVM使用lock指令这样一个标识实现,CPU在识别这样一个标识后,不把前后代码进行排序,这就是volatile中禁止指令重排的原理,硬件有更复杂的实现。

并发修改异常

在对同一数据源同时做迭代并且修改其中数据操作时,即使是线程安全的容器,也会出现该异常。
解决办法:使用CopyOnWriteArrayList代替。注意:添加操作多时,效率低,因为每次添加时都会进行复制,开销非常的大。并发迭代操作多时可以选择。

CountDownLatch原理

用于闭锁

FutureTask

FutureTask也可用于闭锁,因为它也是等待分线程执行完成之后才去获取结果,行为与CountDownLatch类似。

虚假唤醒

为了避免虚假唤醒问题,obj.wait()应该总是使用在循环中

Condition

单个Lock可能与多个Condition对象关联。在Condition对象中,与wait、notify和notifyAll方法对应的分别是await、signal和signalAll。
Condition实例实质上被绑定到一个锁上。要为特定Lock实例获得Condition实例,可以使用newCondition()方法。

使用Condition对象实现线程按序交替

ReadWriteLock

比独占锁性能更优,这种锁是读时可以并发,写时独占。

线程八锁

关键:
①非静态方法的锁默认为this,静态方法的锁为对应的Class实例。
②某一个时刻内,只能有一个线程持有锁,无论几个方法。

线程池

Fork/Join框架

使⽤多线程可能带来什么问题?

并发编程的⽬的就是为了能提⾼程序的执⾏效率提⾼程序运⾏速度,但是并发编程并不总是能提⾼程序
运⾏速度的,⽽且并发编程可能会遇到很多问题,⽐如:内存泄漏、上下⽂切换、死锁还有受限于硬件和软件的资源闲置问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值