系列文章目录
多线程与高并发-多线程(一)
多线程与高并发-synchronized(三)
前言
如果你连synchronized不知道,你好意思说你是混java圈的吗?
synchronized
synchronized 底层实现:对象头记录线程id及是否被锁 (改进后的synchronized效率,不一定比原子操作效率低)
- 锁的是对象不是代码
- 锁是支持重入的
- 锁升级(线程争用:偏向锁升级为自旋锁,10次以后升级为总量级锁–os;只能升级,不能降级)
- 偏向锁(偏向对象先绑定的线程;对象头会有当前绑定的线程的信息;对象头的标志位 markword 两位存储线程信息)
- 自旋锁(默认自旋10次;compareAndSwap-cas CPU原语;自旋时,谁优先呢(涉及公平锁、非公平锁)
- ABA问题,
加version
如果是基础类型无所谓;引用类型,就像你跟前女友复合,你重新拥有了她,但是她已经经历过很多,你懂的
- ABA问题,
- 重量级锁(os系统锁 ,进入等待队列中)
- jdk早期 synchronized 重量级-os 系统级内核态
- 锁升级概念:我是厕所所长(1/2 马士兵)
- cas:适用线程少、执行时间短
- synchronized:适用线程多、执行时间长
- 特性:可见性+原子性
- 问题:基本类型包装类、string 是共享的,可能导致你的代码和其他库源码发生冲突情况
volatile
下一篇文章会专门讲volatile
- 可见性
通过缓存一致性协议实现 - 防止指令重排
通过内存添加读写屏障实现,load、store相互组合实现
例子:单例模式双重检查
双重锁检查
public class TestDoubleCheckLock{
/**
* 测试双重锁单利模式
* volatile:可见性+禁止重排序
*/
private static volatile TestDoubleCheckLock instance;
public void getInstance(){
if(instance==null){
synchronized (TestDoubleCheckLock.class){
System.out.println("11");
if(instance==null){
System.out.println("22");
instance = new TestDoubleCheckLock();
}
}
}
}
@Test
public void testSingle() throws Exception{
ExecutorService pool = Executors.newFixedThreadPool(100);
for(int i=0;i<100;i++){
pool.execute(new Runnable(){public void run(){
getInstance();
}});
}
Thread.sleep(10000);
}
}
我向你奔赴而来,你就是星辰大海