JMM
Java Memory Model
Java内存模型
并发编程
Volatile
被Volatile修饰的变量,所生成的汇编代码,会出现一个Lock前缀指令,相当于一个内存屏障,
- 确保了指令重排序的有序性
- 强制对缓存修改的操作立刻修改到主存,相当于直接对主存进行操作
volatile主要用在多个线程感知实例变量被更改了场合,从而使得各个线程获得最新的值。
为什么需要Volatile
原子类
CAS
不变性
Java锁
互斥与同步
所谓互斥,-- 不能同时运行,一个线程获取到锁,其它线程会被阻塞
是指散布在不同进程之间的若干程序片断,当某个进程运行其中一个程序片段时,其它进程就不能运行它们之中的任一程序片段,只能等到该进程运行完这个程序片段后才可以运行。
所谓同步,-- 不能同时运行的基础上,按照某种先后次序来运行
是指散步在不同进程之间的若干程序片断,它们的运行必须严格按照规定的 某种先后次序来运行,这种先后次序依赖于要完成的特定的任务。
同步是一种更为复杂的互斥,而互斥是一种特殊的同步。
非互斥同步 -- 线程不会阻塞,可以循环尝试
锁的分类
乐观锁 -- 悲观锁
-
悲观锁: -- Synchronized Lock接口
假设一定会发生冲突,获取到锁之后会阻塞其它等待线程 好处是简单安全,但缺点是由于挂起线程和恢复线程都需要转入内核态进行 在真实情况中,发生冲突的概率很小,悲观锁会造成浪费
-
乐观锁:-- 一般通过CAS实现,比如原子类,并发容器等
假设不会发生冲突,尝试操作,失败了再进行其他处理,一般是不断循环重试 如果数据和一开始拿到的不一样,说明数据在这段时间内被修改过,那就不能继续更新,会选择放弃,报错或重试。 比如在数据库中添加版本号
公平锁 -- 非公平锁
读写锁
可重入锁 -- 非可重入锁
自旋锁 -- 自适应锁
可中断锁
偏向锁、轻量级锁、重量级锁
这三种锁是指锁的状态,并且是针对Synchronized,在java通过引入锁升级的机制来实现高效的synchronized
Synchronized
- 对象锁
- 类锁
原理
Java对象头
Synchronized优化
- 无锁状态
- 偏向锁
- 轻量级锁
- 重量级锁
偏向锁
轻量级锁
重量级锁
锁粗化
锁消除
可重入锁
线程调用Synchronized方法的同时在其方法体内部调用另一个synchronized方法, 也就是说一个线程得到一个对象锁后再次请求该对象锁,是允许的。
不可中断
- 中断线程
等待唤醒机制与Synchronized
生产者消费者模式
ReentrantLock
并发容器 工具类
并发容器
ConcurrnetHashMap
- Java7
- Java8
- others
CopyOnWriteArrayList/Set
- 迭代
并发流程控制
CountDownLatch
Semaphore
信号量 许可证
CycicBarrier
可重用
AQS
Abstract Queued Synchronized