美文网首页
Java基础-线程-锁

Java基础-线程-锁

作者: 16325 | 来源:发表于2020-03-31 22:09 被阅读0次

锁的表示

Java里的锁,主要都是对对象进行加锁,如普通的synchronized非静态方法,就是对当前执行方法的对象进行加锁。那么怎么对对象进行加锁呢?对象的锁其实主要就是通过对象头的markOop进行表示的。markOop其实不是一个对象,只是一个字长的数据,在32为机器上,markOop为32个位,在64位上为64个位。markOop中不同的位区域存储着不同的信息,但是需要注意的一点是,markOop每个位区域表示的信息不是一定的,在不同状态下,markWord中存着不同的信息。接下来盗图一张:


image.png

偏向锁

当锁对象第一次被某个线程访问时,它会在其对象头的markOop中记录该线程ID,那么下次该线程再次访问它时,就不需要进行加锁了。但是这中间只要发生了其他线程访问该锁对象的情况,证明这个对象会发生并发,就不能对这个对象再使用偏向锁了,会进行锁的升级。

一句话,有线程请求锁,就在对象头记录此线程ID,就算一直占用了,除非其他线程请求锁,否则永不释放。

轻量锁

使用轻量级锁时,不需要申请互斥量,仅仅将Mark Word中的部分字节CAS更新指向线程栈中的Lock Record,如果更新成功,则轻量级锁获取成功,记录锁状态为轻量级锁;否则,说明已经有线程获得了轻量级锁,目前发生了锁竞争(不适合继续使用轻量级锁),接下来膨胀为重量级锁。

一句话,线程栈中有个对象,有线程请求锁,就在对象头中cas指向线程栈中的这个对象,cas成功了就获得了锁。

重量级锁

轻量级锁膨胀之后,就升级为重量级锁了。重量级锁是依赖对象内部的monitor锁来实现的,而monitor又依赖操作系统的MutexLock(互斥锁)来实现的,所以重量级锁也被成为互斥锁。
为什么说重量级锁开销大呢?主要是,当系统检查到锁是重量级锁之后,会把等待想要获得锁的线程进行阻塞,被阻塞的线程不会消耗cup。但是阻塞或者唤醒一个线程时,都需要操作系统来帮忙,这就需要从用户态转换到内核态,而转换状态是需要消耗很多时间的,有可能比用户执行代码的时间还要长。

在 Hotspot 中这些操作是通过 ObjectMonitor 来实现的,通过它提供的功能就可能做到获取锁,释放锁,阻塞中等待锁释放再去竞争锁,锁等待被唤醒等功能,我们来探讨下它是如何做到的。
每个对象都持有一个 Monitor, Monitor 是一种同步机制,通过它我们就可以实现线程之间的互斥访问,首先来列举下 ObjectMonitor 的几个我们需要讨论的关键字段

_owner,ObjectMonitor 目前被哪个线程持有
_entryList,阻塞队列(阻塞竞争获取锁的一些线程)
_WaitSet,等待队列中的线程需要等待被唤醒(可以通过中断,singal,超时返回等)
_cxq,线程获取锁失败放入 _cxq 队列中
_recursions,线程重入次数,synchronized 是个可重入锁

为每一个对象创建一个monitor结构,在堆中。
1.如果一个java对象被某个线程锁住,则该java对象的Mark Word字段中LockWord指向monitor的起始地址
2.Monitor的Owner字段会存放拥有相关联对象锁的线程id

相关文章

  • Java-并发编程知识点总结

    目录: 线程基础 线程池 各种各样的锁 并发容器 原子类 Java 内存模型 线程协作 AQS 框架 一、线程基础...

  • 并发编程

    并发编程基础 Java线程模型 发生了系统调用的锁,就是重量锁 MMU: 虚拟地址映射 线程类型 用户线程:使用J...

  • 高并发编程总纲

    个人介绍 Java多线程,各种并发集合,线程安全。 Java锁,性能以及效率。 框架netty。在netty基础上...

  • Java synchronized 关键字原理学习

    在上一篇Java 线程 和 锁 基础知识已经介绍了Java中的线程和锁的一些基本概念,现在就来学习和了解下Java...

  • Java 基础篇

    Java 语言的基础也是我们阅读源码和进行代码调优的基础。 Java 基础主要包含以下部分: 语言基础 锁 多线程...

  • 知识梳理目录

    Java基础 Java线程池 AQS之独占锁 AQS之Condition AQS之Condition AQS之同步...

  • 多线程--同步与锁

    同步与锁 上一篇中,笔者介绍了Java多线程的基础知识,主要讲解了进程/线程的区别、Java多线程的创建、Java...

  • Java基础-线程-锁

    锁的表示 Java里的锁,主要都是对对象进行加锁,如普通的synchronized非静态方法,就是对当前执行方法的...

  • Java并发(五):锁

    一. 基础 锁是用来控制多个线程访问共享资源的方式。 Java SE 5 之前,Java程序靠synchroniz...

  • 字节跳动Android实习面试凉凉经

    一面问的Java 和Android基础 Jvm虚拟机 messageQueue会不会阻塞ui线程 对象锁和类锁 之...

网友评论

      本文标题:Java基础-线程-锁

      本文链接:https://www.haomeiwen.com/subject/cqbguhtx.html