【jvm】07-偏向锁、轻量锁、重量锁到底是啥?

欢迎关注b站账号/公众号【六边形战士夏宁】,一个要把各项指标拉满的男人。该文章已在github目录收录。

屏幕前的大帅比大漂亮如果有帮助到你的话请顺手点个赞、加个收藏这对我真的很重要。别下次一定了,都不关注上哪下次一定。

1.概述

多任务处理在现代计算机操作系统中几乎已是一项必备的功能了。在许多场景下,让计算机同时 去做几件事情,不仅是因为计算机的运算能力强大了,还有一个很重要的原因是计算机的运算速度与 它的存储和通信子系统的速度差距太大,大量的时间都花费在磁盘I/O、网络通信或者数据库访问上。这个在 一行代码完成多线程有写过如何分配线程,原理基本一致。

由于计算机 的存储设备与处理器的运算速度有着几个数量级的差距,所以现代计算机系统都不得不加入一层或多 层读写速度尽可能接近处理器运算速度的高速缓存(Cache) 来作为内存与处理器之间的缓冲,但同时引入新的问题即缓存一致性Java虚拟机的即时编译器中也有指令重排序 (Instruction Reorder)优化(详见)。

2.java内存模型

2.1.主内存与工作内存

主内存直接对应于物理硬件的内存,而为了获取更好的运行速度,虚拟机(或者是硬件、操作系统本身的优化措施)可能会让工作内存优先存储于寄存器和高速缓存中,因为程序运行时主要访问的是工作内存。

2.2.内存间交互操作

Java内存模型中定义了以下8种操作来完成:lock(锁定)\unlock(解锁)\read(从主内存读取到工作内存中)\load(放入工作内存副本)\use(载入执行引擎)\assign(赋值)\store(传递至主内存)\write(写入主内存)。即不允许read和load、store和write操作之一单独出现。对一个变量执行unlock操作之前,必须先把此变量同步回主内存中(执行store、write操作)等

2.3.volatile

可以被认为是轻量级同步,仅保证可见性,如下代码则会发现线程2永远不会打印hello,但是当加入volatile就可以打印了

/**
* @author seal email:876651109@qq.com
* @date 2020/11/22 3:20 PM
* @description
*/
public class Concurrence {
public boolean v = false;
// public volatile boolean v = false;
public static void main(String[] args) {
Concurrence c = new Concurrence();
Thread thread1 = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
c.v = true;
System.out.println(c.v);
});
Thread thread2 = new Thread(() -> {
while (true){
if (c.v) {
System.out.println("hello");
}
}
});
thread2.start();
thread1.start();
while (true) { }
}
}

2.4.long和double型变量的特殊规则

因为过去对于这两个值特别的存储方式使其并非原子性,但在JDK9以后可以使用-XX:+AlwaysAtomicAccesses开启

2.5.原子性、可见性与有序性

原子性:java内存模型中的除lock和unlock外其他6个均具备原子性,synchronized为大范围原子性操作。

可见性:除了volatile之外,Java还有两个关键字能实现可见性,它们是synchronized和final.

有序性:volatile和synchronized

3.java与线程

3.1.内核线程

程序一般不会直接使用内核线程,而是使用内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP),轻量级进程就是我们通常意义上所讲的线程

3.2.线程调度

调度主要方式有两种,分别是协同式(Cooperative Threads-Scheduling)线程调度和抢占式(Preemptive Threads-Scheduling)线程调度。但前者并不稳定。

3.3.状态转换

6种线程状态:新建(new)\运行(start)\无限期等待(需被显式唤醒,主要有wait、join未设置参数)\限期等待(sleep、wait、join等)、阻塞(synchronized)、结束(shutdown)

4.java与协程

4.1.用户线程

用户线程需要自行维护不如内核线程方便使用,但这部分可以交由虚拟机完成,目前仍在fork/join中研发。研发成熟可以让线程切换消耗更低的资源,而且更加轻量仅占1MB

5.线程安全

5.1.Java语言中的线程安全

5.1.1.不可变

String、final以及基本数据类型

5.1.2.绝对线程安全

synchronized修饰

5.1.3.相对线程安全

例如vector、HashTable等使用同步手段

5.2.线程安全的实现方法

5.2.1.互斥同步

synchronized以及JDK5后新起的java.util.concurrent.locks.Lock

5.2.2.非阻塞同步

即CAS等实现

6.锁优化(AQS)

6.1.自旋锁与自适应自旋

即有限次数的while(true),优点是避免线程切换

6.2.锁消除

例如某个同步方法中全程使用线程安全方法

6.3.锁粗化

例如在循环中不停加锁解锁,则直接会移到循环外面

6.4.轻量级锁

如果整个过程jvm判断只有无竞争但有多个线程可能会使用时进行替换,由CAS实现,如果竞争过多则变为重量锁

6.5.偏向锁

如果整个过程jvm判断没有竞争关系,则进行锁消除处理,在该锁被其它线程获取时依据轻量锁标记判断退化为轻量锁还是重量锁

参考资料

《深入理解Java虚拟机》-周志明

【jvm】07-偏向锁、轻量锁、重量锁到底是啥?的更多相关文章

  1. java 偏向锁,轻量锁,重量级锁

    synchronized的执行过程: 1. 检测Mark Word里面是不是当前线程的ID,如果是,表示当前线程处于偏向锁 2. 如果不是,则使用CAS将当前线程的ID替换Mard Word,如果成功 ...

  2. 重量级锁synchronized的优化----自旋锁、自适应自旋锁、锁消除、锁粗化

    synchronized是重量级锁,效率不高.但在jdk 1.6中对synchronize的实现进行了各种优化,使得它显得不是那么重了.jdk1.6对锁的实现引入了大量的优化,如自旋锁.自适应自旋锁. ...

  3. synchronized实现原理及其优化-(自旋锁,偏向锁,轻量锁,重量锁)

    1.synchronized概述: synchronized修饰的方法或代码块相当于并发中的临界区,即在同一时刻jvm只允许一个线程进入执行.synchronized是通过锁机制实现同一时刻只允许一个 ...

  4. Java synchronized实现原理总结和偏量锁、轻量锁、重量锁、自旋锁

    synchronized实现同步的基础:Java中的每一个对象都可以作为锁.具体表现为以下3种形式. 对于普通同步方法,锁是当前实例对象(this). 对于静态同步方法,锁是当前类的Class对象. ...

  5. 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

    网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...

  6. 写文章 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!

    网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...

  7. synchronized与static synchronized 的差别、synchronized在JVM底层的实现原理及Java多线程锁理解

    本Blog分为例如以下部分: 第一部分:synchronized与static synchronized 的差别 第二部分:JVM底层又是怎样实现synchronized的 第三部分:Java多线程锁 ...

  8. Linux 自旋锁,互斥量(互斥锁),读写锁

    自旋锁(Spin Lock) 自旋锁类似于互斥量,不过自旋锁不是通过休眠阻塞进程,而是在取得锁之前一直处于忙等待的阻塞状态.这个忙等的阻塞状态,也叫做自旋. 自旋锁通常作为底层原语实现其他类型的锁. ...

  9. java里的锁总结(synchronized隐式锁、Lock显式锁、volatile、CAS)

    一.介绍 首先, java 的锁分为两类: 第一类是 synchronized 同步关键字,这个关键字属于隐式的锁,是 jvm 层面实现,使用的时候看不见: 第二类是在 jdk5 后增加的 Lock ...

随机推荐

  1. 商业爬虫学习笔记day1

    day1 一. HTTP 1.介绍: https://www.cnblogs.com/vamei/archive/2013/05/11/3069788.html http://blog.csdn.ne ...

  2. Java 总纲

    Java基础篇 Java资源下载 IntelliJ IDEA为类和方法自动添加注释 为什么JAVA对象需要实现序列化? maven ubantu安装maven Java Maven项目搭建 maven ...

  3. Spring Cloud Feign原理详解

    目录 1.什么是Feign? 2.Open Feign vs Spring Cloud Feign 2.1.OpenFeign 2.2.Spring Cloud Open Feign 3.Spring ...

  4. Javaj基础知识runtime error

    遇到的java 运行时错误: NullPointerException空指针  ,简单地说就是调用了未经初始化的对象或者是不存在的对象,这个错误经常出现在创建图片,调用数组这些操作中,比如图片未经初始 ...

  5. treeTable实现排序

    /* * * TreeTable 0.1 - Client-side TreeTable Viewer! * @requires jQuery v1.3 * * Dual licensed under ...

  6. Linux shell实现每天定时备份mysql数据库

    每天定时备份mysql数据库任务,删除指定天数前的数据,保留指定天的数据: 需求: 1,每天4点备份mysql数据: 2,为节省空间,删除超过3个月的所有备份数据: 3,删除超过7天的备份数据,保留3 ...

  7. 【Spark】【RDD】从本地文件系统创建RDD

    练习作业 完成任务从文件创建三个RDD(math bigdata student) cd ~ touch math touch bigdata touch student pwd 启动Spark-sh ...

  8. selenium 控制窗口无限向下滚动

    使用脚本 window.scrollBy(0, 1000),放入 while True 循环,示例代码: while True: js = 'window.scrollBy(0, 1000)' dri ...

  9. 【教程】OBS直播推流教程(Windows & macOS)

    OBS Open Broadcaster Software | OBS (obsproject.com) Windows直播推流教程 Windows下OBS直播推流非常简单,本教程将会介绍,具体步骤如 ...

  10. Table.AlternateRows删除间隔….Alternate…(Power Query 之 M 语言)

    数据源: "姓名""基数""个人比例""个人缴纳""公司比例""公司缴纳"&qu ...