首页  >  问答  >  正文

java - 一个类的对象锁只有一个,类锁呢?

一个类的对象锁只有一个,如果有几个非静态函数都是synchronized,在某一时刻只有一个线程能调用其中一个函数

假如一个类有几个静态函数是synchronized,在某一时刻只有一个线程能调用其中一个静态函数吗?也就是类锁也只有一个吗?

高洛峰高洛峰2744 天前702

全部回复(6)我来回复

  • 巴扎黑

    巴扎黑2017-04-18 10:51:00

    前面一种锁的是实例对象,锁定了当前的那个对象,如果有多个实例对象,这些synchronized方法之间不是同步的。第二种锁的是类对象,类对象就一个,所以是同步的。

    回复
    0
  • PHP中文网

    PHP中文网2017-04-18 10:51:00

    public class Foo {
    
        synchronized void test1() {
            //to implements
        }
    
        void test2() {
            synchronized(this) {
                //to implements
            }
        }
    
        synchronized static void test3() {
            //to implements
        }
    
        static void test4() {
            synchronized(Foo.class) {
                //to implements
            }
        }
    }

    如上代码,test1方法相当于test2,当this是同一个对象时,会发生阻塞。当然,不同对象没有关系,因为this不一样。称为对象级锁。
    test3相当于test4,这里是用class对象作为锁,因为一般情况下一个类的类实例只有一个,那么每次进入这个方法都会锁。称为类级锁。

    回复
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:51:00

    • 非静态同步方法(A)用的锁就是当前实例对象本身,一个实例的A获取锁之后,该实例的其他A必须等待锁的释放,多个实例用的都是不同的锁;

    • 静态同步方法(B)用的锁是类对象本身,一旦一个B获取锁之后其他的B都必须等待释放锁,不管是一个实例还是多个实例;

    另外 A和B之间用不同的锁,所以不会有竞争关系;

    回复
    0
  • ringa_lee

    ringa_lee2017-04-18 10:51:00

    Class类创建一个对象就是代表一个普通类,这时“类锁”就是这个实例对象上的锁

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:00

    你说的是“互斥锁”的概念,针对synchronized修饰方法有两种情况:

    【非静态方法】

    当一个方法被synchronized修饰后,锁对象为当前方法所属对象,即方法中的this。

    【静态方法】

    当一个静态方法被synchronized修饰后,该静态方法上锁的对象为当前类对象(Class类的实例)。每个类都有唯一的一个类对象。获取类对象的方式:类名.class。

    而对于互斥的场景,需要理解两点说明:

    1、静态方法与非静态方法同时声明了synchronized,他们之间是非互斥关系的。原因在于,静态方法锁的是类对象而非静态方法锁的是当前方法所属对象。

    2、当Synchronized修饰的是两段不同的代码,但是锁对象相同时,两个线程分别调用者两段代码时就是互斥的

    所以你说的“一时刻只有一个线程能调用其中一个函数”(即互斥),判断条件就是锁对象是否相同,与方法类型无关。

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-18 10:51:00

    对象方法的synchronized修饰,锁为对象自身,也就是this;
    静态方法的synchronized修饰,锁为Class对象自身,也就是由类加载器创建的类对象;

    回复
    0
  • 取消回复