Synchronized实现原理及和Lock的区别
Synchronized
偏向锁,轻量级锁 ,重量级锁
偏向锁:对象头存储线程ID,可重入(根据线程ID判断)
轻量级锁:复制对象头到Lock Record 记录锁信息,拥有锁 复制的Lock Rrecord 指向对象头,自旋获取锁
重量级锁:moniter监控 ,阻塞
Synchronized不同使用方法区别:
可重入锁
可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。说的有点抽象,下面会有一个代码的示例。
对于Java ReentrantLock而言, 他的名字就可以看出是一个可重入锁,其名字是Re entrant Lock重新进入锁。
对于Synchronized而言,也是一个可重入锁。可重入锁的一个好处是可一定程度避免死锁。
synchronized void setA() throws Exception{
Thread.sleep(1000);
setB();
} synchronized void setB() throws Exception{
Thread.sleep(1000);
}上面的代码就是一个可重入锁的一个特点,如果不是可重入锁的话,setB可能不会被当前线程执行,可能造成死锁。
Synchronized和ReentrantLock区别:
1.比Synchronized更灵活
2.lock()获取锁,unlock()释放锁,要手动在finally中调用unlock()释放锁。
3.Synchronized惊群效应
Synchronized中的wait和notify ,而Lock是借助于Condition类实现,更灵活,可以选择性的进行线程通知,在调度线程上更加灵活。
Synchronized惊群效应,当有一个线程获取锁时候,其他线程进入WaitSet队列,wait()之后的nofity()时线程在争夺同一把锁的时候是随机的,谁抢到就给谁。 notifyAll() 会有一种惊群效应,一旦锁被释放了,所有的wait线程被唤醒。被通知的线程是有JVM 随机选择的 ,Synchronized就相当于整个Lock对象中只有一个单一的Condition对象,所有的线程都注册在它一个对象的身上,线程开始notiifyAll()时,需要通知所有的WAITING线程,没有选择权,会出现相当大的效率问题。
4.Lock对象可以创建多个Condition(对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以选择性的进行线程的通知,在调度线程上更加灵活。
Lock lock=new ReentrantLock();
Condition condition=lock.newCondition();
condition.await();
condition.signal();
condition.signalAll();
Condition中的signalAll
/** 从Condition中移动所有的等待线程到 拥有锁队列里
* Moves all threads from the wait queue for this condition to
* the wait queue for the owning lock.
* 是 queue队列而不是waitSet 集合
* @throws IllegalMonitorStateException if {@link #isHeldExclusively}
* returns {@code false}
*/
public final void signalAll() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignalAll(first);
}
/**
* Removes and transfers all nodes.
* @param first (non-null) the first node on condition queue
*/
private void doSignalAll(Node first) {
lastWaiter = firstWaiter = null;
do {
Node next = first.nextWaiter;
first.nextWaiter = null;
transferForSignal(first);
first = next;
} while (first != null);
}
为什么会有偏向锁,轻量级锁,重量级锁:
1.为什么要引入偏向锁?
因为经过HotSpot的作者大量的研究发现,大多数时候是不存在锁竞争的,常常是一个线程多次获得同一个锁,因此如果每次都要竞争锁会增大很多没有必要付出的代价,为了降低获取锁的代价,才引入的偏向锁。
2.为什么要引入轻量级锁?
轻量级锁考虑的是竞争锁对象的线程不多,而且线程持有锁的时间也不长的情景。因为阻塞线程需要CPU从用户态转到内核态,代价较大,如果刚刚阻塞不久这个锁就被释放了,那这个代价就有点得不偿失了,因此这个时候就干脆不阻塞这个线程,让它自旋这等待锁释放。
3.轻量级锁什么时候升级为重量级锁?
自旋的时间太长也不行,因为自旋是要消耗CPU的,因此自旋的次数是有限制的,比如10次或者100次,如果自旋次数到了线程1还没有释放锁,或者线程1还在执行,
线程2还在自旋等待,这时又有一个线程3过来竞争这个锁对象,那么这个时候轻量级锁就会膨胀为重量级锁。重量级锁把除了拥有锁的线程都阻塞,防止CPU空转。
重量级锁线程会被挂起park,耗性能
Synchronized的锁升级过程
Synchronized实现原理及和Lock的区别的更多相关文章
- (转)synchronized和lock的区别
背景:最近在准备java基础知识,对于可重入锁一直没有个清晰的认识,有必要对这块知识进行总结. 1 . 什么是可重入锁 锁的概念就不用多解释了,当某个线程A已经持有了一个锁,当线程B尝试进入被这个锁保 ...
- Java中synchronized和Lock的区别
synchronized和Lock的区别synchronize锁对象可以是任意对象,由于监视器方法必须要拥有锁对象那么任意对象都可以调用的方法所以将其抽取到Object类中去定义监视器方法这样锁对象和 ...
- 详解synchronized与Lock的区别与使用
知识点 1.线程与进程 在开始之前先把进程与线程进行区分一下,一个程序最少需要一个进程,而一个进程最少需要一个线程.关系是线程–>进程–>程序的大致组成结构.所以线程是程序执行流的最小单位 ...
- Java synchronized和 Lock 的区别与用法
在分布式开发中,锁是线程控制的重要途径.Java为此也提供了2种锁机制,synchronized和lock.做为Java爱好者,自然少不了对比一下这2种机制,也能从中学到些分布式开发需要注意的地方. ...
- 同步锁Synchronized与Lock的区别?
synchronized与Lock两者区别: 1:Lock是一个接口,而Synchronized是关键字. 2:Synchronized会自动释放锁,而Lock必须手动释放锁. 3:Lock可以让等待 ...
- Synchronized和lock的区别和用法
一.synchronized和lock的用法区别 (1)synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized可以加在方法上,也可以加在特定代码块中,括号中表示需要 ...
- Synchronized与Lock的区别与应用场景
转载. https://blog.csdn.net/fly910905/article/details/79765381 同步代码块,同步方法,或者是用java提供的锁机制,我们可以实现对共享资源变量 ...
- synchronized 与 lock 的区别
synchronized 和 lock 的用法区别 synchronized(隐式锁):在需要同步的对象中加入此控制,synchronized 可以加在方法上,也可以加在特定代码块中,括号中表示需要锁 ...
- java - synchronized与lock的区别
synchronized与lock的区别 原始构成 synchronized是关键字属于JVM层面 monitorenter(底层是通过monitor对象来完成,其实wait/notify等对象也依赖 ...
随机推荐
- L1141
一,看题 1,位于0格可移动到相邻得1格.位于1格可移动到相邻的0格上. 2,从某一格开始可以移动的格子数.(应该不能重复,否则不久循环了.那就意味着我们可以要标记喽?) 3 二,写题 1,你是一次一 ...
- 思科ASA对象组NAT
ACL对象组NAT配置 ciscoasa#conf t ciscoasa(config)#hostname ASA ASA(config)#domain-name asa.com ASA(config ...
- BZOJ 4197: [Noi2015]寿司晚宴 状压dp+质因数分解
挺神的一道题 ~ 由于两个人选的数字不能有互质的情况,所以说对于一个质因子来说,如果 1 选了,则 2 不能选任何整除该质因子的数. 然后,我们发现对于 1 ~ 500 的数字来说,只可能有一个大于 ...
- 2-ESP8266 SDK开发基础入门篇--非RTOS版与RTOS版
https://www.cnblogs.com/yangfengwu/p/11071580.html 所有的源码 https://gitee.com/yang456/Learn8266SDKDevel ...
- [RN] React Native 生成 Android APK
在用模拟器或者真机调试完App后,需要将App打包成Apk发布文件. 下面简单记录下打包步骤: 第一:生成签名密钥 这一步的操作主要是生成需要的签名密钥,供android调用,生成的文件待用 在项目根 ...
- HEXO快速搭建自己的博客
关注我,每天都有优质技术文章推送,工作,学习累了的时候放松一下自己. 本篇文章同步微信公众号 欢迎大家关注我的微信公众号:「醉翁猫咪」 很多人有自己的博客,那么你想要吗?利用Hexo就可以搭建专属自己 ...
- shell脚本编程基础之for循环
循环结构 循环需要有进入条件和退出条件,如果没有退出条件,则就会一直循环下去 for 变量 in 列表:do 循环体 done 生成列表及示例 {1..100}:生成1到100的整数列表 `comma ...
- GoCN每日新闻(2019-10-17)
GoCN每日新闻(2019-10-17) 通过go module管理go tool https://marcofranssen.nl/manage-go-tools-via-go-modules/ 使 ...
- mysql 数据插入insert
mysql> select * from user; +------+----------+-----------+ | id | name | address | +------+------ ...
- P3709 大爷的字符串题(莫队+结论)
题目 P3709 大爷的字符串题 做法 有一个显然的结论:一段区间里最小答案为众数的个数 用莫队来离线求众数 \(tmp_i\)表示出现\(i\)次的数的个数,\(num_i\)表示\(i\)出现的次 ...