学习Java基础知识,打通面试关~十三锁机制

在java中,我们进行多线程操作的时候,一般都会用到锁的机制。并且在锁中我们一般用到的是synchronized和ReentrantLock两种,当然还有更加细化的读写锁。我们这里api的使用不讲解。在学习锁机制之前,我们需要了解几个概念。

  • 原子性:相关操作中,不会被其他线程干扰,安全的运行到结束。一般通过同步操作来实现。
  • 可见性:当某个线程修改了共享变量。其状态可以立刻让其他线程了解到。通常解释为本地内存数据反映到主内存上。关键字volative字就是这么做的。
  • 有序性: 保持线程内的串行语义,避免指令重排。

在了解上面几个意义之后,我们开始学习下java中的锁机制。

synchronized

该锁在使用方式可以参考我原先写的Java多线程系列文章

我们知道synchronized的锁机制是建立在monitorenter/monitorexit指令上的。基本单元是Monitor。

在jdk1.6之前Monitor之前主要是依赖操作系统内部的机制来实现同步的。这样实现的锁机制在执行时会消耗很大的资源,导致锁机制同步的很慢。

在jdk1.6以后锁机制进行了修改,主要修改的方向是在jvm上的修改。改变了锁机制采用了锁的升降级操作。里面涉及到的偏向锁,轻量级锁,重量级锁。

  • 偏向锁:利用的机制也是CAS操作(compare and swap)
  1. 这是一种加锁操作的优化。核心是 一个线程获得锁 ,那么就先会进入偏向模式。此时在MarkWord的节后也会变成偏向锁的结构。
  2. 当当前线程要再次获取锁时。无需做同步操作直接获得,省去了中间的锁申请的操作。
  3. 如果锁竞争比较激烈,那么偏向锁就会失败,进而升级为轻量级锁。
  • 轻量级锁:
  1. 偏向锁进行失败的时候或者关闭偏向锁时,升级为轻量级锁。在MarkWord中的结构也变为轻量级锁的结构。
  2. 依据:对于大部分的锁而言,在整个周期内不存在竞争的关系。如果竞争激烈的情况下轻量级锁要比重量级锁效率更低。
  3. 在 轻量级锁操作时,如果MarkWord已经不是指向当前线程的栈帧,那么说明该锁对象已经被其他线程占领,轻量级锁会膨胀微重量级锁,后面的线程会进入阻塞状态。
  • 重量级锁

重量级锁是通过我们所说的Monitor基本单元实现的。。这是对象的内部监视器。该主要依赖底层的操作系统Mutex Lock实现,操作系统实现线程间的切换需要利用到用户态和内核态的切换。成本较高。

ReentrantLock

ReentrantLock建立在AQS(AbstractQueuedSynchronizer)的操作上的。

  1. 该锁机制更加灵活方便,可以设置锁的公平性,获取释放锁等。
  2. AbstractQueuedSynchronizer是独占的同步器,内部使用 exclusiveOwnerThread表示独占的线程,并且使用CLH锁队列来将并发执行改成串行执行,整个队列是一个双向的链表,每个CLH锁队列的节点会保存前一个节点和后一个节点的引用,当前节点对应的线程,一集一个状态。这个状态表示线程是否阻塞block.
  3. 锁获取主要分为两个部分,第一阶段是初次进行竞争主要来烤火节点是否分为公平锁还是不公平锁。 第二阶段是在CHL队列中的锁,依赖CAS操作保证原子操作。使队列并发操作改成了串行操作。消除并发带来的问题
  4. ReentrantLock 是一个轻量级的锁。

原文发布于微信公众号 - LuckQI(YoungRUIQ)

原文发表时间:2018-07-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏雨过天晴

转 PHP-redis编译成功

18130
来自专栏Linux驱动

15.linux-LCD层次分析(详解)

如果我们的系统要用GUI(图形界面接口),这时LCD设备驱动程序就应该编写成frambuffer接口,而不是像之前那样只编写操作底层的LCD控制器接口。 什么是...

27960
来自专栏编程心路

一文读懂SpringMVC中的文件上传与下载

这两天研究了一下 SpringMVC 中文件上传与下载,也遇到了一些坑,这里做个总结。

42140

访问数据 - 反应方式(Vert.x入门的第4部分)

原文地址:https://dzone.com/articles/accessing-data-the-reactive-way

1.2K40
来自专栏散尽浮华

Linux系统下的用户密码设定梳理

随着linux使用的普遍,对于linux用户以及系统的安全要求越来越高,而用户密码复杂程度是系统安全性高低的首要体现。因此如何对linux下用户的密码进行规则限...

32990
来自专栏实战docker

Java实战操作MongoDB集群(副本集)

Spring提供了MongoDB操作的工具:MongoTemplate,使得在Spring环境下对MongoDB的操作更为便利,本章我们就来学一下如何用Mong...

36090
来自专栏老码农专栏

ActFramework R1.4.0 带来 WebSocket 的支持

12130
来自专栏*坤的Blog

公司web安全等级提升

公司的一个web数据展示系统,本来是内网的,而且是一个单独的主机,不存在远程控制的问题,所以之前并没有考虑一些安全相关的测试.但是国调安全检查的需要添加这样子的...

22540
来自专栏唐维黎的专栏

Web 性能压测工具 ApacheBench(ab)使用总结

对于 web 服务,不管是上新,还是平时产品运营,节假日活动等,在这之前都需要评估现网压力承受能力,提前进行扩容,并做到防患于未然。所以对网站性能压力测试是必不...

1.9K00
来自专栏java达人

ThreadLocal与Spring 事务管理

编写线程安全代码的关键是管理程序中的共享可变状态,除了通过synchronized加锁机制防止多个线程同时访问同一段数据外,还有一种方法就是通过ThreadLo...

250100

扫码关注云+社区

领取腾讯云代金券