ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

一路谈谈锁

2021-12-21 23:31:33  阅读:129  来源: 互联网

标签:lock 一路 -------------------- 谈谈 线程 内存 32 bits


Synchronized

一、使用

修饰类的:实例方法、静态方法、代码块;

实例方法:锁对象为当前实例对象:

public synchronized void sayHello(){
	System.out.println("Hello World");
}

静态方法:锁对象为当前类Class对象:

public static synchronized void sayHello(){
	System.out.println("Hello World");
}

代码块:

//锁对象
synchronized(this){}
//锁对象
synchronized(""){}
//锁class
synchronized(xxx.class){}

二、原理

2.1、Java对象头(Object Header)

普通对象:

|--------------------------------------------------------------|
|                     Object Header (64 bits)                  |
|------------------------------------|-------------------------|
|        Mark Word (32 bits)         |    Klass Word (32 bits) |
|------------------------------------|-------------------------|

数组对象:

|--------------------------------------------------------------|
|                     Object Header (64 bits)                  |
|------------------------------------|-------------------------|
|        Mark Word (32 bits)         |    Klass Word (32 bits) |
|------------------------------------|-------------------------|

其中Mark Word(32位,JVM为32位):

|-------------------------------------------------------|--------------------|
|                  Mark Word (32 bits)                  |       State        |
|-------------------------------------------------------|--------------------|
| identity_hashcode:25 | age:4 | biased_lock:1 | lock:2 |       Normal       |
|-------------------------------------------------------|--------------------|
|  thread:23 | epoch:2 | age:4 | biased_lock:1 | lock:2 |       Biased       |
|-------------------------------------------------------|--------------------|
|               ptr_to_lock_record:30          | lock:2 | Lightweight Locked |
|-------------------------------------------------------|--------------------|
|               ptr_to_heavyweight_monitor:30  | lock:2 | Heavyweight Locked |
|-------------------------------------------------------|--------------------|
|                                              | lock:2 |    Marked for GC   |
|-------------------------------------------------------|--------------------|

  • identity_hashcode:自身hashcode
  • age:分代年龄,只有4位,最大值为15,所以-XX:MaxTenuringThreshold最大值为15;
  • thread:偏向锁的线程ID
  • lock::锁状态标记位,用尽可能少的二进制位表示尽可能多的信息。该标记的值不同,整个mark word表示的含义不同。
  • biased_lock:是否启用偏向锁,1启用,0没有。
  • state:
    • Normal:正常(无状态)。lock:01;biased_lock:0
    • Biased:偏向锁。lock:01;biased_lock:1
    • Lightweight Locked:轻量级锁。lock:00;
    • Heavyweight Locked:重量级锁。lock:10;
    • Marked for GC:GC。lock:11;

2.2、Monitor 监视器

在这里插入图片描述

  • WaitSet:线程调wait()时进入;
  • EntryList:阻塞等待队列。
  • Owner:获取锁的线程。

todo:原理过程:

三、内存可见性

synchronized能解决内存可见性问题,被synchronized加锁后,他会做出以下操作:

  1. 获取同步锁;
  2. 清空内存;
  3. 从主内存中拷贝新的对象副本到工作线程中;
  4. 继续执行代码,刷新主内存的数据;
  5. 释放同步锁;

四、总结:

  • 可保证原子性;
  • 可保证内存可见性;获取锁,从主内存获取最新;释放锁,把最新写入主内存;简单读取最新变量可用volatile;
  • 注意死锁:A和B线程分别持有A和B锁,分别等待B和A锁;应按顺序申请;
  • 可重入性:重入和退出时有计数器增减;

volatile关键字

内存可见性就是多个线程共享访问和操作相同的变量,但一个线程对一个共享变量的修改,另一个线程并不能马上被看到,甚至永远也看不到。

在计算机的系统中,除了内存。数据还会被缓存在CPU的寄存器以及各种缓存中,当访问一个变量时,可能直接从寄存器或CPU缓存中获取,而不一定到内存中去取,当修改一个变量时,也可能是先写到缓存中,稍后才会同步更新到内存中。在单线程的程序中,这一般不是问题。但是在多线程的程序中,尤其是在有很多CPU的情况下,这就是严重的问题。一个线程对内存的修改,另一个线程看不到,一是修改没有及时同步到内存,二是另一个线程根本就没从内存读。

标签:lock,一路,--------------------,谈谈,线程,内存,32,bits
来源: https://blog.csdn.net/code_agent/article/details/122074619

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有