详解java 对象锁与类锁

 更新时间:2020年09月04日 10:11:37   作者:孟应杰  
这篇文章主要介绍了java 对象锁与类锁的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下

一.什么是对象锁

对象锁也叫方法锁,是针对一个对象实例的,它只在该对象的某个内存位置声明一个标识该对象是否拥有锁,所有它只会锁住当前的对象,而并不会对其他对象实例的锁产生任何影响,不同对象访问同一个被synchronized修饰的方法的时候不会阻塞,
例如:

public class MyObject {
  private synchronized void method1(){
    try {
      System.out.println(Thread.currentThread().getName());
      Thread.sleep(4000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  //synchronized修饰为同步方法,如果先调用method1,则4秒后才会调用method2
  //如果不用synchronized修饰,则可以直接异步调用,没有影响
  private void method2(){
    System.out.println(Thread.currentThread().getName());
  }
}

创建一个类,synchronized修饰普通方法,即为对象锁,那么这个时候,多个线程访问同一个对象实例的这个方法时,是会同步的,并且只有一个线程执行完,另一个线程才会执行:

public static void main(String[] args) {
    //创建一个对象
    MyObject myObject=new MyObject();
 
    Thread t1=new Thread (new Runnable() {
      @Override
      public void run() {
        myObject.method1();
      }
    },"t1");
    Thread t2=new Thread (new Runnable() {
      @Override
      public void run() {
        myObject.method1();
      }
    },"t2");
    t1.start();
    t2.start();
}

即,打印t14秒之后,t2才会打印,因为两个线程调用的是同一个对象实例的方法,即同一把锁,所有会同步执行
而如果是不同对象实例的话,则没有影响,因为两个线程调用的是不同实例的锁方法,即不是同一把锁,没有关系,所以会正常输出,不会同步

public static void main(String[] args) {
    //创建两个对象
    MyObject myObject=new MyObject();
    MyObject myObject01=new MyObject();
 
    Thread t1=new Thread (new Runnable() {
      @Override
      public void run() {
        myObject.method1();
      }
    },"t1");
    Thread t2=new Thread (new Runnable() {
      @Override
      public void run() {
        myObject01.method1();
      }
    },"t2");
    t1.start();
    t2.start();
  }

二 对象锁的几种形式以及应用案例

1 synchronized修饰普通方法属于对象锁,

2 synchronized修饰的代码块传入this也属于对象锁

应用:减小锁粒度,第二种形式就比较好,比如A线程调用一个同步方法需要很长时间,那么B就要等待很长时间,这个时候可以将必须同步的代码使用synchronized代码块, 不需要同步的先执行,节约资源

三 类锁

类锁是锁住整个类,当有多个线程来声明这个类的对象时候将会被阻塞,直到拥有这个类锁的对象呗销毁或者主动释放了类锁,这个时候在被阻塞的线程被挑选出一个占有该类锁,声明该类的对象。其他线程继续被阻塞住

(上面百度的),即一句话,不管多少个对象,多少个对象,共用一把多,且只有一把,不管怎么调用,都会同步

上面方法加static变类锁:

private static synchronized void method1(){
    try {
      System.out.println(Thread.currentThread().getName());
      Thread.sleep(4000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

  这个时候无论线程调用的是多少个对象实例的方法,都会同步

四 类锁形式

synchronized修饰静态方法属于类锁

以上就是详解java 对象锁与类锁的详细内容,更多关于java对象锁与类锁的资料请关注脚本之家其它相关文章!

相关文章

  • java实现纸牌游戏之小猫钓鱼算法

    java实现纸牌游戏之小猫钓鱼算法

    这篇文章主要为大家详细介绍了java实现纸牌游戏之小猫钓鱼算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • JWT令牌的工作原理详解

    JWT令牌的工作原理详解

    这篇文章主要介绍了JWT令牌的工作原理详解,在认证的时候,当用户用他们的的凭证成功登录以后,一个JSON Web Token将会被返回,此后,用户名和密码就不再是用户的凭证,而token是用户用来访问资源的新凭证了,需要的朋友可以参考下
    2023-08-08
  • MyEclipse如何取消默认工作空间方法示例

    MyEclipse如何取消默认工作空间方法示例

    这篇文章主要介绍了MyEclipse如何取消默认工作空间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • 使用Java编写一个好用的解析配置工具类

    使用Java编写一个好用的解析配置工具类

    这篇文章主要为大家详细介绍了如何使用Java编写一个好用的解析配置工具类,支持解析格式有properties,yaml和yml,感兴趣的可以了解下
    2024-11-11
  • Springmvc中的转发重定向和拦截器的示例

    Springmvc中的转发重定向和拦截器的示例

    本篇文章主要介绍了Springmvc中的转发重定向和拦截器的示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Spring使用注解进行对象装配(DI)的操作

    Spring使用注解进行对象装配(DI)的操作

    获取Bean对象也叫做对象装配,就是把对象取出来放到某个类中,有时候也叫对象注入,这篇文章主要介绍了Spring使用注解进行对象装配(DI),需要的朋友可以参考下
    2023-07-07
  • JFinal实现伪静态的方法

    JFinal实现伪静态的方法

    JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。这篇文章主要介绍了JFinal实现伪静态,需要的朋友可以参考下
    2018-04-04
  • java排序算法之选择排序详解

    java排序算法之选择排序详解

    这篇文章主要为大家详细介绍了java排序算法之选择排序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-05-05
  • 一文带你了解Java中的SPI机制

    一文带你了解Java中的SPI机制

    SPI 全称是 Service Provider Interface,是一种 JDK 内置的动态加载实现扩展点的机制,本文主要为大家介绍了SPI机制的原理与使用,需要的可以参考一下
    2023-04-04
  • Netty分布式ByteBuf使用SocketChannel读取数据过程剖析

    Netty分布式ByteBuf使用SocketChannel读取数据过程剖析

    这篇文章主要为大家介绍了Netty源码分析ByteBuf使用SocketChannel读取数据过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03

最新评论