惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
Lohrmann on Cybersecurity
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
腾讯CDC
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Microsoft Azure Blog
Microsoft Azure Blog
G
Google Developers Blog
TaoSecurity Blog
TaoSecurity Blog
博客园_首页
Vercel News
Vercel News
Hugging Face - Blog
Hugging Face - Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Last Week in AI
Last Week in AI
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
The Exploit Database - CXSecurity.com
量子位
Project Zero
Project Zero
A
Arctic Wolf
小众软件
小众软件
NISL@THU
NISL@THU
C
CERT Recently Published Vulnerability Notes
有赞技术团队
有赞技术团队
MongoDB | Blog
MongoDB | Blog
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
News and Events Feed by Topic
宝玉的分享
宝玉的分享
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Troy Hunt's Blog
P
Privacy & Cybersecurity Law Blog
Security Latest
Security Latest
B
Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
D
DataBreaches.Net
Schneier on Security
Schneier on Security
The Hacker News
The Hacker News
K
Kaspersky official blog
C
Check Point Blog
Hacker News: Ask HN
Hacker News: Ask HN
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Webroot Blog
Webroot Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
人人都是产品经理
人人都是产品经理
AI
AI
Cisco Talos Blog
Cisco Talos Blog
MyScale Blog
MyScale Blog
Cloudbric
Cloudbric
B
Blog RSS Feed
S
Schneier on Security
P
Palo Alto Networks Blog

vzard's blog

二叉搜索树的一些性质 - vzard's blog 跳表 - vzard's blog redis的事务 - vzard's blog redis数据类型及使用场景 - vzard's blog 二叉树非递归遍历统一写法 - vzard's blog 灵魂七问 - vzard's blog XPath线索追踪技术 - vzard's blog cron表达式小记 - vzard's blog 计算广告核心问题总结 - vzard's blog 实现一个简单的http服务器 - vzard's blog 由三次握手想到的... - vzard's blog Js原型链解读 - vzard's blog 统计知识(1) - vzard's blog 同步Github上的fork - vzard's blog Http协议杂谈 - vzard's blog JAVA虚拟机的类加载机制 - vzard's blog HashMap源码剖析 - vzard's blog 关于volatile - vzard's blog 修复hexo博客的一个bug - vzard's blog
Java中的锁 - vzard's blog
vzardlloo · 2017-09-07 · via vzard's blog

这篇博客主要讲一下Java中的各种各样五花八门的锁。这些五花八门的锁肯定不是工程师没事做闲着无聊倒腾出来的,他们都是为了在某些环境下的性能而对传统的锁做了些改造。

公平锁和非公平锁

公平锁是指当多个线程在等待同一锁时,必须按照申请锁的先后顺序排成一个等待队列依次来一次获得锁。
非公平锁是指加锁时不用考虑排队等待问题,直接尝试获取锁,获取不到自动到队尾等待,是抢占式的。
对比:非公平锁的性能比公平锁搞5~10倍,因为公平锁需要在多核的情况下维护一个队列。但是非公平锁有可能会导致饥饿问题。

自旋锁

由于Java的线程是映射到操作系统的原生线程上的,如果要阻塞一个线程或者唤醒一个线程,都需要操作系统来帮忙完成,需要操作系统从用户态转换到核心态。因此状态转换需要耗费很多处理器时间。同时虚拟机的开发团队注意到许多应用上共享数据的锁定状态只会持续很短的一段时间,如果一个线程只是很短暂的占用一个共享资源,当在它短暂占用这段资源的时候如果有别的线程试图占用这个资源的时候,后来的线程会因为该资源被占用而陷入阻塞状态,丢失对时间片的占用,这会导致资源的大量浪费。所以针对这种情况开发团队设计出了自旋锁,即如果物理机器有一个以上的处理器,可以让两个或两个以上的线程同时并行执行,我们就可以让后面的线程“稍等一下”,但是不放弃处理器的执行时间,看看持有锁的线程是否很快就会释放锁。为了让线程等待,我们只需让线程执行一个忙循环(自旋),等待锁被释放。
但是自旋也不可以替代锁,自旋虽然避免了线程切换的开销,但是它是要占用处理器时间的,因此,如果锁被占用的时间很短,自旋等待的效果会非常好。如果锁被占用的时间很长。那么自旋只会白白占用处理器的资源。因此自旋等待时间必须要有一定限制,如果自旋超过一定次数(默认是10次,使用-XX:PreBlockSpin来更改)没有获得锁,就应该使用传统的方式去挂起线程了。需要注意的是自旋是在轻量级锁中使用的,在重量级锁中,线程不能用自旋锁。

偏向锁

偏向锁是JDK6中引入的一项锁优化,它的目的是消除数据在无竞争情况下的同步原语,进一步提高程序的运行性能。

偏向锁会偏向于第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其他的线程获取,则持有偏向锁的线程将永远不需要同步。大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,为了让线程获得锁的代价更低而引入了偏向锁。

悲观锁和乐观锁

悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。
乐观锁:假定不会发生并发冲突,只在提交操作时检测是否违反数据完整性。(使用版本号或者时间戳来配合实现)

共享锁和排它锁

共享锁:如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排它锁。获准共享锁的事务只能读数据,不能修改数据。
排它锁:如果事务T对数据A加上排它锁后,则其他事务不能再对A加任何类型的锁。获得排它锁的事务即能读数据又能修改数据

读写锁

读写锁是一个资源能够被多个读线程访问,或者被一个写线程访问但不能同时存在读线程。Java当中的读写锁通过ReentrantReadWriteLock实现。

还有其他的一些锁这里不一一列举。