Java开发热门前沿知识,oh

     0: aload_0
     1: invokespecial #1                  // Method java/lang/Object."<init>":()V
     4: return
  LineNumberTable:
    line 9: 0

public synchronized void testRoller();
descriptor: ()V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=1, args_size=1
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Roller Running!
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 14: 0
line 15: 8

public void testRunning();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: ldc #5 // class com/design/model/singleton/SynchronizeDetail
2: dup
3: astore_1
4: monitorenter
5: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
8: ldc #3 // String Roller Running!
10: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
13: aload_1
14: monitorexit
15: goto 23
18: astore_2
19: aload_1
20: monitorexit
21: aload_2
22: athrow
23: return
Exception table:
from to target type
5 15 18 any
18 21 18 any
LineNumberTable:
line 17: 0
line 18: 5
line 19: 13
line 20: 23
StackMapTable: number_of_entries = 2
frame_type = 255 /* full_frame /
offset_delta = 18
locals = [ class com/design/model/singleton/SynchronizeDetail, class java/lang/Object ]
stack = [ class java/lang/Throwable ]
frame_type = 250 /
chop */
offset_delta = 4
}


观察一下编译后的代码,在testRoller()方法中有这样一行描述flags: ACC_PUBLIC, ACC_SYNCHRONIZED,表示着当前方法的访问权限为SYNCHRONIZED的状态,而这个标志就是编译后由JVM根据Synchronized加锁的位置增加的锁标识,也称作类锁,凡是要执行该方法的线程,都需要先获取Monitor对象,直到锁被释放以后才允许其他线程持有Monitor对象。以HotSport虚拟机为例Monitor的底层又是基于C++ 实现的ObjectMonitor,我不懂C++,通过查资(百)料(度)查到了这个ObjectMonitor的结构如下:

ObjectMonitor::ObjectMonitor() {
_header = NULL;
_count = 0;
_waiters = 0,
_recursions = 0; //线程重入次数
_object = NULL;
_owner = NULL; //标识拥有该monitor的线程
_WaitSet = NULL; //由等待线程组成的双向循环链表
_WaitSetLock = 0 ;
_Responsible = NULL ;
_succ = NULL ;
_cxq = NULL ; //多线程竞争锁进入时的单向链表
FreeNext = NULL ;
_EntryList = NULL ; //处于等待锁block状态的线程的队列,也是一个双向链表
_SpinFreq = 0 ;
_SpinClock = 0 ;
OwnerIsThread = 0 ;
}


那么接下来就用一张图说明一下多线程并发情况下获取testRoller()方法锁的过程

![](https://upload-images.jianshu.io/upload_images/22932333-eb5817c355f456ac.image?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

上文中提到了MutexLock,而图中加解锁获取Monitor对象就是基于它实现的互斥操作,再次强调,在加解锁过程中线程会存在内核态与用户态的切换,因此牺牲了一部分性能。

再来说一下testRunning()方法,很显然,在编译后的class中出现了一对monitorenter/monitorexit,其实就是对象监视器的另一种形态,本质上是一样的,不过区别是,对象在锁实例方法或者实例对象时称作内置锁。而上面的testRoller()是对类(对象的class)的权限控制,两者互不影响。

到这里就解释Synchronized的基本概念,接下来要说一说它到底跟对象在对空间的内存布局有什么关系。

# Synchronized与对象堆空间布局

还是以64位操作系统下HotSport版本的JVM为例,看一张全网都搜的到的图

![](https://upload-images.jianshu.io/upload_images/22932333-28c39fc8884dd9f7.image?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

图中展示了MarkWord占用的64位在不同锁状态下记录的信息,主要有对象的HashCode、偏向锁线程ID、GC年龄以及指向锁的指针等,记住这里的GC标志记录的位置,将来的JVM文章也会用到它,逃不掉的。在上篇例子中查看内存布局的基础上稍微改动一下,代码如下:

/**

  • FileName: JavaObjectMode
  • Author: RollerRunning
  • Date: 2020/12/01 20:12 PM
  • Description:查看加锁对象在内存中的布局
    */
    public class JavaObjectMode {
    public static void main(String[] args) {
    //创建对象
    Student student = new Student();
    synchronized(student){
    // 获得加锁后的对象布局内容
    String s = ClassLayout.parseInstance(student).toPrintable();
    // 打印对象布局
    System.out.println(s);
    }
    }
    }

class Student{
private String name;
private String address;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

}


第一张图是上篇文章的也就是没加锁时对象的内存布局,第二张图是加锁后的内存布局,观察一下VALUE的值

![](https://img-blog.csdnimg.cn/img_convert/0237aed3baefa17612e0ba9105bc3745.png)

![](https://img-blog.csdnimg.cn/img_convert/b26a161d2612f43ed7a24c19e3c69697.png)



### 最后在出来放一波福利吧!希望可以帮助到大家!

> [**戳此获取免费学习资料**](https://gitee.com/vip204888/java-p7)

千千万万要记得:多刷题!!多刷题!!

之前算法是我的硬伤,后面硬啃了好长一段时间才补回来,算法才是程序员的灵魂!!!!

篇幅有限,以下只能截图分享部分的资源!!

(1)多线程(这里以多线程为代表,其实整理了一本JAVA核心架构笔记集)

![image](https://img-blog.csdnimg.cn/img_convert/524391390f49058e839b418c1be534e2.png)

(2)刷的算法题(还有左神的算法笔记)

![image](https://img-blog.csdnimg.cn/img_convert/f81baeeb2cbdd0ab8151a80025fa4df0.png)

(3)面经+真题解析+对应的相关笔记(很全面)

![image](https://img-blog.csdnimg.cn/img_convert/d969758c783a73c062e3352f0b3dcf13.png)

(4)视频学习(部分)

> ps:当你觉得学不进或者累了的时候,视频是个不错的选择

![image](https://img-blog.csdnimg.cn/img_convert/bfc6313148b65c8b5546bbdf1a9b740b.png)

其实以上我所分享的所有东西,有需要的话我这边可以免费分享给大家,但请一定记住获取方式:[点击这里前往免费获取](https://gitee.com/vip204888/java-p7)

频学习(部分)

> ps:当你觉得学不进或者累了的时候,视频是个不错的选择

[外链图片转存中...(img-SQtaXiGC-1628283050554)]

其实以上我所分享的所有东西,有需要的话我这边可以免费分享给大家,但请一定记住获取方式:[点击这里前往免费获取](https://gitee.com/vip204888/java-p7)

在这里,最后只一句话:祝大家offer拿到手软!!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值