ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JAVA锁机制

2022-10-30 16:34:47  阅读:189  来源: 互联网

标签:javaJDK java 虚拟机 布局 数据 代码 程序


icode9锁机制

一、介绍

icode9锁机制是用于建立线程间同步的基础,并非是JAVA中独特的概念。本篇大致讲JAVA中的锁,按照锁分类,有下列几种锁

公平锁/非公平锁 可重入锁/不可重入锁 独占锁/共享锁 互斥锁/读写锁 乐观锁/悲观锁 分段锁 偏向锁/轻量级锁/重量级锁 自旋锁

但这些锁并不完全指的是锁,有的是锁设计,有的是锁状态,也有的是锁的特性。

下面就推荐一下关于这些锁

二、公平锁/非公平锁

1. 公平锁

就是指当多个线程都要申请锁时,需要根据申请锁的先后排序来进行获得。

2. 非公平锁

指当多个线程申请锁时,无法确认哪一个线程会获得锁,与申请的先后顺序无关

非公平锁相较于公平锁,吞吐量上会更具优势。JAVA中的synchronized关键字和ReentrantLock都是非公平锁,但ReentrantLock是利用AQS实现的线程调度,所以可以**使ReentrantLock变为公平锁;**synchronized则没有办法变为公平锁。

三、icode9可重入锁/不可重入锁

1. 可重入锁

顾名思义就是说可以重复获得的锁,但只有对于同一个的线程。对于同一个线程来说,如果该对象现在获得到了该锁并且没有释放,那么它可以持续获得该锁而不会造成死锁。

2. 不可重入锁

与可重入锁相反,即使是同一个线程,在持有锁的情况下再次申请该锁,也同样导致死锁的现象。也就是说这种锁不可以递归调用,一旦递归调用容易导致死锁。

ReentrantLock翻译出来就是可重入锁,所以听名字就明白他是可重入的,而synchronized实际上也是一个可重入锁

如何判定一个锁是否使可重入锁呢?

class Test{ public void a(){ ReentrantLock lock = new ReentrantLock(true); lock.lock(); // 重复调用锁不会造成死锁即是不可重入锁 lock.lock(); } }

四、独占锁/共享锁

1. 独占锁

在同一时间只有一个线程可以获得到这个锁,也就是说不会存在两个线程同时持有一把锁的状况,当一个线程获取到锁,其他线程就会阻塞。

2. 共享锁

允许有多个线程同时获得到该锁,不同线程获取同一把锁时不会阻塞。

五、互斥锁/读写锁

1. 互斥锁

互斥锁的效果和概念类似于独占锁,都是在同一时刻只有有一个线程获得到锁。(我不太清楚互斥锁和独占锁之间或许有意义,有清楚的朋友可以留言告诉我一下。)

2. 读写锁

读写锁就是一种互斥锁。我们了解多线程读文件不会导致并发原因,但多线程写就存在并发原因。所以在读-读的画面下是不存在互斥关系的,但在读-写,写-写的画面下是存在互斥关系的,当一个线程持有了写锁,那么其它任何线程都不能获取读锁或者写锁。

读写锁是一种特殊的独占锁,因为读-读的画面下并不存在互斥关系,而读-写,写-写的画面下存在互斥关系,所以读写锁更适用于读多写少的场景。

六、乐观锁/悲观锁

1. 乐观锁

乐观锁实际上并不是锁,他总是乐观的觉得在他要修改数据的之后,其他线程不会进行更改。仅仅只有在升级数据的之后计算数据能否被取消。我们通常使用CAS算法+版本号进行实现。

单纯使用CAS算法的话存在ABA问题,也就是说数据从A变到了B,又从B变了A,这时候CAS算法就会觉得数据没有发生更改。所以我们必须添加版本号解决该现象,每次对数据的操作就会让版本号+1,从而应对该现象。

2. 悲观锁

悲观锁和自信锁相反,他失望的觉得每天更改数据都存在任何线程同时设置,于是经常更改数据就会对资源上锁,阻塞其他线程。

JAVA中synchronized和ReentrantLock都是悲观锁。

七、分段锁

分段锁不是一种实际存在的锁,他是一种锁的设计观念。有的之后我们只能仅仅想要更改部分数据,但我们却必须将整个对象锁住,这会导致一定的特性想法,而即使我们仍然对必须更改的那一段数据进行加锁的话,效率都会高这些。但是分段锁也并不是越多越好,当我们必须进行统计的之后,我们就必须获得到全部的分段锁才可以进行统计。

八、偏向锁/轻量级锁/重量级锁

这几个锁也只是是实际的锁,而是一种JAVA中锁的状况。JAVA中锁从低到高有下面几个状态

无锁 偏向锁 轻量级锁 重量级锁

这几个锁状态是JVM为了提升锁的获得质量而提起来的,使用在synchronized中。

1. 锁升级

我们常说的锁升级就是指在竞争锁的过程中,根据竞争的残酷程度,锁的状况出现由低到高的转化,且这些变革过程是不可逆的。这种状况被称为锁升级。

锁状态 竞争锁状况 描述 偏向锁 基本无竞争 若一段代码仍然被同一个线程执行,则这个线程就会自动得到这个锁。 轻量级锁 较少竞争 若锁处于偏向锁状态,且有另一个线程申请该锁,则升级为轻量级锁,其他线程会利用自旋的方法进行等待,不会阻塞。 重量级锁 较多竞争 当锁处于偏向锁状态,且任何线程自旋的数量超过一个阈值时,就会升级为重量级锁,对任何线程进行阻塞,性能会有所下降。

九、自旋锁

自旋可以解释为自己原地转圈等待,而在代码里的展现方式就是循环。CAS算法其实就是一种自旋的实现。

在CAS中有几个值V,E,N。V是目前值,E是希望的变量值,N是函数的新值。当且仅当V==E时就会将N复制给V。

十、icode9总结

锁机制的原因是应对线程安全问题,而使用锁机制可能会导致性能的减少,因为从并发变为了同步。悲观锁、独占锁等会导致线程阻塞,比较重,为了尽可能的降低对效能的妨碍,就发生了消极锁,自旋锁,通过任何形式来超过线程安全的原因,但这些锁一般只使用在并发量不高的状况下。因为读写的特点,可以存在同时读,但不能存在同时写,于是有了读写锁。

每种锁的发生都有它的作用,对于我们上层开发人员来说难的不是使用锁,而是判定在哪个状态下才会使用哪种锁,在应对并发现象的此外尽可能的降低对效能的妨碍。

标签:javaJDK,java,虚拟机,布局,数据,代码,程序
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有