对象锁和类锁是否会互相影响?

  • 对象锁

  在代码中的方法上加了synchronized的锁,或者synchronized(this)的代码段。

  Java的所有对象都含有一个互斥锁,这个锁由jvm自动获取和释放。线程进入synchronized方法的时候获取该对象的锁,但如果已经有线程获取了这个对象的锁,那么当前线程会等待;synchronized方法正常返回或者抛异常而终止,jvm会自动释放对象锁。这里也体现了用synchronized来加锁的一个好处,方汉抛异常的时候,锁仍然可以由jvm来自动释放。

  假设我有一个类ClassA,其中有一个方法synchronized methodA(),那么当这个方法被调用的时候,我们获得就是对象锁。

    • 举例:

    ClassA a = new ClassA();

    ClassA b = new ClassA();

    那么如果在a这对象上调用了methodA,不会影响b这个对象,也就是说对于b这个对象,他也可以调用methodA,因为这是两个不同的对象,所以说对象锁是针对对象的。

  • 类锁

  在代码中的方法上加了static和synchronized的锁,或者synchronized(xxx.class)的代码段;

  对象锁是用来控制实例方法之间的同步,类锁是用来控制静态方法(或静态变量互斥体)之间的同步。其实类锁只是一个概念上的东西,并不是真实存在的,它只是用来帮助我们理解锁定实例方法和静态方法的区别的。我们知道,java类可能会有很多个对象,但是只有一个Class对象,也就是说类的不同实例之间共享该类的Class对象。Class对象其实也仅仅是一个java对象。所以所谓的类锁,不过是Class对象的锁而已。获取类的Class对象有好几种,最简单的就是MyClass.class的方式。

  例如有一个类ClassA,其中有一个方法synchronized static methodA(),注意这个方法是静态的,那就是说这个类的所有对象都公用这个方法,那如果在这个类的某个对象上调用了这个方法,那么其他的对象如果想要用这个方法就得待着锁被释放,所以感觉就好像这个类被锁住了一样。

  • 私有锁

  在类内部声明一个私有属性,如private Object lock,在需要加锁的代码段synchronized(lock)。

  • 类锁和对象锁不是同一个东西

  一个是类的Class对象的锁,一个是类的实例的锁。也就是说:一个线程访问静态synchronized的时候,允许另一个线程访问对象的实例synchronized方法。反过来也是成立的,因为他们需要的锁是不同的,因此类锁和对象锁不会产生竞争,二者的加锁方法不会相互影响

原文地址:https://www.cnblogs.com/johnnyzhao/p/14139896.html