java 对象锁学习

时间:2021-09-08 11:06:04

机制

  锁机制是用来解决多线程共享资源时产生的冲突问题的。java 为每一个对象关联一个对象锁,通常把锁分为对象锁和类锁,他们的本质都是对象锁,只不过对象锁关联的是类的 Object 对象 (java.lang.Object),而类锁关联的是类的 Class 对象 java.lang.Class。
  jvm 对每个锁都有一个计数

  • 若该计数为 0,则锁没有被占用,可以被访问它的线程来持有
  • 一个对象的对象锁已被某个线程持有,新的线程来访问时将被挂起,知道持有它的线程释放该锁并且计数为 0
  • 一个线程已经持有了某个对象的锁,该线程再次访问该对象锁时可以重入,且计数 +1
  • 一个线程释放对象锁时,该锁的计数 -1,当某个锁的计数为 0 时锁被释放,可以被线程竞争

分类

  • 不管怎么分类,java 中通过 synchronized 来实现的锁其本质都是对象锁
  • java 内部同步机制实现通常有两种方式,synchronized 修饰方法和语句块
  • synchronized 关键字作用于对象,这个对象可以是类的实例对象,也可以是 Class 对象

    • 类锁

  1 public class SyncObject {
2 // 类锁1:通过static方法加同步锁
3 public static synchronized void syncMethod1() {
4 try {
5 System.out.println("testMethod1 start!");
6 Thread.sleep(3000);
7 } catch (InterruptedException e) {
8 e.printStackTrace();
9 }
10 System.out.println("testMethod1 end!");
11 }
12
13 public void syncMethod2() {
14 // 类锁2:通过同步语句块传递Class类型参数
15 synchronized (SyncObject.class) {
16 try {
17 System.out.println("testMethod2 start!");
18 Thread.sleep(3000);
19 } catch (InterruptedException e) {
20 e.printStackTrace();
21 } finally {
22 System.out.println("testMethod2 end!");
23 }
24 }
25 }
26 }

类锁作用于类的 Class 对象,对一个类来说,无论该类有多少个实例,它的静态变量和静态方法都只有一份,保存在 Class 对象中。通过对 Class 对象加锁来实现的同步语句或同步方法,无论该对象的哪个实例来访问,都需要竞争这个类锁

  • 对象锁

  1 public class SyncObject {
2 // 对象锁1(方法锁):通过方法加同步锁
3 public synchronized void syncMethod1() {
4 try {
5 System.out.println("testMethod1 start!");
6 Thread.sleep(3000);
7 } catch (InterruptedException e) {
8 e.printStackTrace();
9 }
10 System.out.println("testMethod1 end!");
11 }
12
13 public void syncMethod2() {
14 // 对象锁2:通过同步语句块传递Object类型参数
15 synchronized (this) {
16 // 此处的参数可以是本实例this,也可以是其它实例比如new SyncObject(),传入哪个实例就对哪个实例加锁
17 try {
18 System.out.println("testMethod2 start!");
19 Thread.sleep(3000);
20 } catch (InterruptedException e) {
21 e.printStackTrace();
22 } finally {
23 System.out.println("testMethod2 end!");
24 }
25 }
26 }
27 }

对象锁会对类的实例对象加锁,每一个 new 操作都会获得一个新的实例对象,对于 synchronized 修饰的非 static 方法或传递参数为实例对象的语句块,各个实例对象会拥有自己的锁。

TIPS

    • synchronized 的作用范围是对象

    • synchronized 修饰的代码块需要传入一个对象参数(这个对象可以使 Class 对象),这个对象参数就是它的作用范围
    • synchronized 修饰的非静态方法的作用范围是 this,即当前对象实例。修饰静态方法时作用范围是这个类,即 Class 对象
  1. synchronized 的粒度针不可再分

    因为锁是针对整个对象的,所以当某个对象的锁被持有后,其它线程不能持有该锁

    • 当一个线程调用某个对象 a 的 synchronized 方法(a.syncMethod1)在该方法结束之前,该对象的其它 synchronized 方法 (a.syncMethod2..) 都将不能被调用。同步代码块 synchronized(a)与 a.syncMethod1 有同样的作用周期
    • 当一个线程调用某个类 A 的 static synchronized 方法(A.staticSyncMethod1)在该方法结束前,该类的其它 static synchronized 方法(A.staticSyncMethod2..)都将不能被调用
    • 当一个线程调用某个对象 a 的 synchronized 方法(a.syncMethod1)在该方法结束之前,该类的其它 static synchronized 方法 (A.syncMethod2..) 还可以被调用,反之也成立
    • synchronized 的只对它修饰的模块加锁

    • 未被 synchronized 修饰的模块是可以被异步访问的, 因为线程访问它的时候并不需要获取对象锁

java 对象锁学习的更多相关文章

  1. [转]Java 对象锁-synchronized()与线程的状态与生命周期

      线程的状态与生命周期 Java 对象锁-synchronized() ? 1 2 3 4 synchronized(someObject){   //对象锁 } 对象锁的使用说明: 1.对象锁的返 ...

  2. java 对象锁和类锁的区别(转)

    java 对象锁和类锁的区别   转自; ) ); ; ) ); 上述的代码,第一个方法时用了同步代码块的方式进行同步,传入的对象实例是this,表明是当前对象,当然,如果需要同步其他对象实例,也不可 ...

  3. Java对象锁和类锁全面解析(多线程synchronized关键字)

    最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没 ...

  4. JAVA对象头详解(含32位虚拟机与64位虚拟机)

    为什么要学习Java对象头 学习Java对象头主要是为了解synchronized底层原理,synchronized锁升级过程,Java并发编程等. JAVA对象头 由于Java面向对象的思想,在JV ...

  5. ------------------java collection 集合学习 ----小白学习笔记,,有错,请指出谢谢

    <!doctype html>java对象集合学习记录 figure:first-child { margin-top: -20px; } #write ol, #write ul { p ...

  6. Java核心知识点学习----线程中如何创建锁和使用锁 Lock&comma;设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  7. 【Thread】java线程之对象锁、类锁、线程安全

    说明: 1.个人技术也不咋滴.也没在项目中写过线程,以下全是根据自己的理解写的.所以,仅供参考及希望指出不同的观点. 2.其实想把代码的github贴出来,但还是推荐在初学的您多亲自写一下,就没贴出来 ...

  8. Java并发包下锁学习第一篇&colon;介绍及学习安排

    Java并发包下锁学习第一篇:介绍及学习安排 在Java并发编程中,实现锁的方式有两种,分别是:可以使用同步锁(synchronized关键字的锁),还有lock接口下的锁.从今天起,凯哥将带领大家一 ...

  9. Java并发包下锁学习第二篇Java并发基础框架-队列同步器介绍

    Java并发包下锁学习第二篇队列同步器 还记得在第一篇文章中,讲到的locks包下的类结果图吗?如下图: ​ 从图中,我们可以看到AbstractQueuedSynchronizer这个类很重要(在本 ...

随机推荐

  1. 读取properties配置文件的方法

    一般在.properties文件中配置数据库连接的相关信息,我们需要从中读取信息,以便建立与数据库的连接. 文件目录: application.properties配置信息: url=jdbc:ora ...

  2. Echarts的相关问题记录与应用

    一.相关问题记录: 1.对图表的div进行隐藏操作,使用hide()或display:none,重新展示时,会造成图表无法获取高度,导致图表的高宽不符合预期: 解决方法:最后调用一下resize()函 ...

  3. dedecms为后台自定义菜单的完整方法

    dedecms为后台自定义菜单的完整方法 品味人生 dedeCMS 围观7330次 18 条评论 编辑日期:2014-06-14 字体:大 中 小   最近在给客户定制一个企业网站,客户要求使用ded ...

  4. 经验总结17--submitbutton,ajax提交

    发篇小文章,纪念七七事变. submit一般用于提交表单,可是想使用ajax进行提交,又想按"enter"触发button. 那么就阻止提交表单的事件,进行自己定义的提交. 1.让 ...

  5. Photoshop理论:另外一种角度看图层混合模式

    源地址:http://www.missyuan.com/thread-687724-1-4.html 1.我将一个色阶看成是一个由亮部和暗部组成的这么一个元素,亮部是我们看的见的,暗部是影响亮部的,有 ...

  6. Excel教程&lpar;10&rpar; - 逻辑运算符

    AND 用途:所有参数的逻辑值为真时返回 TRUE(真):只要有 一个参数的逻辑值为假,则返回 FALSE(假). 语法:AND(logical1,logical2,  ). 参数:Logical1, ...

  7. Windows&lowbar;server&lowbar;2012-r2&lowbar;x64安装教程

    版本: Windows_server_2012-r2_x64 工具: VMware vSphere Client 镜像地址: http://www.xpgod.com/soft/10718.html( ...

  8. CentOS 7安装Tomcat8

    一.安装环境 tomcat的安装依赖于Java JDK,需要先安装配置正确的JDK http://www.cnblogs.com/VoiceOfDreams/p/8376978.html 二.安装包准 ...

  9. Treemap 有序的hashmap。用于排序

    TreeMap:有固定顺序的hashmap.在需要排序的Map时候才用TreeMap. Map.在数组中我们是通过数组下标来对其内容索引的,键值对. HashMap HashMap 用哈希码快速定位一 ...

  10. 和我一起学习爬虫之HTTP&sol;HTTPS抓包工具--Fiddler

    HTTP/HTTPS抓包工具--Fiddler Fiddler[ˈfɪdlə(r)] 1. HTTP代理神器Fiddler Fiddler是一款强大Web调试工具,它能记录所有客户端和服务器的HTTP ...