Java 的锁

Wesley13
• 阅读 523

对象锁:

new一个对象,都会给这个实例创建一把锁,对象中的方法必须在实例创建后,通过调用方法获取锁,一个线程进去这个方法之前拿到对象的锁,才能调用方法,否则被阻塞,举个例子,老王有个如花似玉的女儿,小张很爱慕,但是小张必须见到老王(A a = new A();),通过老王的肯定才能和对方的女儿交往(a.lock());

如果见不到老王,就别想和老王女儿见面(获取锁才能获取共享的资源的操作权利);

小张获取了老王的认可, 和老王女儿交往了,现在小李也喜欢美女,老王说,不能脚踏两只船,等他们分手再说,小李就一直等,后来终于分手了,小李就和美女见面,开始了恋爱。(共享资源在一个线程获取到锁,另一个线下会等待)

可重入锁:

老王有两个女儿,小李都喜欢,老王肯定了小李的为人,说,和我大女儿谈,不适合分手,不用再找我,就可以跟我小女儿谈,

Lock和sync锁 :

因为老王(sync)不通人情,考察的重点比较多,想和老王女儿谈恋爱太难 了;

就通过媒婆(lock),小刘通过媒婆介绍,约了美女。过了两个月不合适,恋爱结束,媒婆直接把小刘劝走了,然后把下一个候选人小杜介绍来了。(lock 锁 有个lock 方法加锁, unlock 方法解锁,控制共享代码 的执行权)

这里,老王效率低,媒婆效率高(jdk1.6之前),后面,老王感觉女儿毕竟亲生的,又做了变通(锁优化。不要当场见面啦,打个电话也行,没房没车没存款也凑合,能陪我老头喝酒也可以

),

公平锁:

老王(非公平锁)是个俗人,追求女儿人很多,有些人排了好长时间队,但是老王说,高富帅什么的优先;导致一堆追求者生气,(sync 是个非公平锁, 锁放开,所有的线程都有获取锁的权利)

媒婆(非公平锁)不一样,每个单身狗都交钱了,客户上地,可以按照排队顺序约美女。(默认也是非公平锁,但是可以开启公平锁)

锁中断:

老王和霸道说,你既然追求我女儿了,就必须等,不能放弃,放弃就是瞧不起我,等一年等三年,也得等,谁叫你喜欢过我女儿,(sync 锁, 一个线程再进入 同步方法的时候, 拿不到锁就一直等, 一会等拿到锁, 才能往后面走)

媒婆不一一样,毕竟做生意的,说,那个妹子太难追求,你换一个吧,不收你钱,(lock 锁可以控制中断 , 如果一个线程长时间没获取锁, 可以中断)

非自旋锁:

小何爱慕美女好久,之前老王这么说,追求我女儿?我女儿条件好,等哪天她单身了,我打电话给你,虽然真单身了,但是老王喝酒忘了!小何多等了三年。(每个线程再阻塞就会等待)

自旋锁:

小何说,女神啊女神,等到你爸的电话,我估计都老了,就不断打电话骚扰老王,每天打几个,老王这边也是没办法,终于女儿说失恋了,老王马上打电话给小何说,你去谈恋爱吧,别他妈打我电话了。(自旋锁会 自旋,询问是否锁放开了,非自旋不会)

锁消除:

老谢也有个女儿,长相不敢恭维。已经30岁没人要,老谢说,我不管你了,谁要你就要,不要房不要车。(锁消除会消除安全代码的锁)

细分锁粒度:

小李和美女谈恋爱,又是看电影买花,又是天天唱歌送礼物,搞浪漫,花了一堆时间,效率极低,小唐看着着急,直接送了一步保时捷,不必要的步骤就过了,然后就和美女同居了,

偏向锁:

jdk6做的锁优化,对象头存储状态,继续举例子,小唐和美女热恋,每次来到老王家里,老王都要去开门,累的要死,后来想到个主意,安装一个机器,把小唐头像和女儿的恋爱状态存进去,如果是热恋,并且男朋友还是小唐,就自动开门,自己啥也不管(偏向锁在对象的对象头有个状态位 ,而且记录的当前获取锁的线程ID, 如果是1 并且当前线程ID, 当该线程再进入方法, 不会加锁)

轻量级锁:

女儿还是热恋状态,但是发现,男朋友不是之前考察过得小唐,老王赶紧丢下自己的事,把新男朋友拉到小仓库拷问,你老婆和你妈掉到水里你先救谁,简单问了个问题,感觉很满意,就说你们谈吧,(偏向锁升级为轻量级锁)

独占锁(排他锁):

女儿不能脚踏两只船,一次只能一个人谈。

非独占锁(共享锁):

主要针对的是读操作, 老王的女儿 虽然不能同时交往, 但是所有单身男青年都有看 美女的权利

悲观锁:

老王(sync)和媒婆 lock 都是 悲观锁,认为竞争一定会发生。女儿条件这么优秀, 管你是王思聪还是胡歌, 必须通过老王的考核。

乐观锁:

1 、mysql ,有版本号的概念,比如加个字段,获取上条记录版本号, update,如果是1 , 就成功, 是0就没更新。

2、Java atomic 包下的类, 基于 CAS,compare and swap,不用锁的,使用 volatile 关键字, 保证可见性, 也可以说, volatile 是一种轻量级的 synchronized 锁

点赞
收藏
评论区
推荐文章
执键写春秋 执键写春秋
3年前
notifyAll唤醒线程的范围?
今天看到开源中国上有这样一个问答:假设我有两个对象锁,对象A锁有5个线程在等待,对象B锁有3个线程在等待,对象A锁中的线程执行完,这时调用notifyAll,是唤醒了对象AB两个锁的全部的等待线程还是只唤醒了A锁的5个线程?1.方法文档解释通过看该方法文档的解释,可以得出下面结论:notifyAll()中All的含义是所有的线程,而不是所有的锁,只能唤
Wesley13 Wesley13
2年前
java锁学习(二)
类锁类锁!!!!java类有很多对象,但是只有一个class对象!!!!所以,类锁,就是针对当前类的Class对象的锁类锁同一时刻只能被一个对象获取1.synchronized放在static方法上(静态锁)2.synchronized放在class对象上静态锁classSyncClassSt
Easter79 Easter79
2年前
synchronize底层原理
1、普通同步方法,锁是当前实例对象2、静态同步方法,锁是当前类的class对象3、同步方法块,锁是括号里面的对象synchronize底层原理:Java虚拟机中的同步(Synchronization)基于进入和退出Monitor对象实现,无论是显式同步(有明确的monitorenter和monitorexit指令,即同步代
Wesley13 Wesley13
2年前
Java学习笔记7
lock接口实现类ReentrantLock我们可以用lock对象,来对临界资源加锁,只有获得lock对象才能访问临界资源,如果没有获得lock对象,就会进入lock对象的锁池。trylock()方法会返回布尔值,这个方法是用来判断这个锁对象是不是已经被线程获取,如果返回值为true,则会直接获得这个锁对象,如果返回false,线程不会阻塞还会继
Stella981 Stella981
2年前
Python的锁
互斥锁锁通常被用来实现对共享资源的同步访问。为每一个共享资源创建一个Lock对象,lLock()创建一个锁,初始状态是未锁定当你需要访问该资源时,调用l.acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线程需等待其被释放),待资源访问完后,再调用l.release方法释放锁!(https:
Wesley13 Wesley13
2年前
Java多线程
wait()方法方法wait()的作用是使当前执行代码的线程进行等待,wait()方法是Object类的方法,该方法用来将当前线程置入“预执行队列”中,并且在wait()所在的代码行处停止执行,直到接到通知或被中断为止。注意:  在调用wait()之前,线程必须获得该对象的对象级别锁,否则会抛出illegal
Wesley13 Wesley13
2年前
Java多线程进阶干货(2)
问题1:子类可以调用父类的同步方法吗?/    一个同步方法可以调用另外一个同步方法,一个线程已经拥有某个对象的锁,  再次申请时,仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的   这里是继承中有可能发生的情形,子类调用父类的同步方法 /public class Test09 {    sy
Wesley13 Wesley13
2年前
Java多线程锁释放
Java多线程运行环境中,在哪些情况下会使对象锁释放?由于等待一个锁的线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不再需要锁的时候及时释放锁是很重要的。在以下情况下,持有锁的线程会释放锁:(1)执行完同步代码块,就会释放锁。(synchronized)(2)在执行同步代码块的过程中,遇到异常而导致线程终止,锁也会被释放。(exc
Wesley13 Wesley13
2年前
Java线程中的同步
!(https://static.oschina.net/uploads/space/2018/0207/164552_Gl6r_3643112.jpg)1、对象与锁每一个Object类及其子类的实例都拥有一个锁。其中,标量类型int,float等不是对象类型,但是标量类型可以通过其包装类来作为锁。单独的成员变量是不能被标明为同步
Wesley13 Wesley13
2年前
Java并发编程总结(一)Syncronized解析
Syncronized解析作用:(1)确保线程互斥的访问同步代码(2)保证共享变量的修改能够及时可见(3)有效解决重排序问题。用法:(1)修饰普通方法(锁是当前实例对象)(2)修饰静态方法(锁是当前对象的Class对象)(3)修饰代码块(锁是Synchonized括号里配置的