Java 教程说:“同一对象上的同步方法的两次调用不可能交错。”

这对于静态方法意味着什么?由于静态方法没有关联的对象,那么synchronized关键字是否会锁定类而不是对象?

有帮助吗?

解决方案

  

由于静态方法没有关联的对象,将synchronized关键字上的锁类,而不是对象?

是。 :)

其他提示

只是为了一个小细节添加到奥斯卡(令人愉悦的简洁!)答案,在Java语言规范的相关章节是的 8.4.3.6, '同步方法'

  

一个同步方法获取监视器它执行(§17.1)之前。对于一类(静态)方法中,使用具有用于该方法的类的类对象相关联的显示器。对于一个实例方法,与此相关的监视器(为其调用方法的对象)被使用。

你必须要小心约(若干程序员通常落入陷阱)的是,有同步静态方法和sync'ed非静态方法,即,之间没有联系的一个点:

class A {
    static synchronized f() {...}
    synchronized g() {...}
}

主:

A a = new A();

主题1:

A.f();

主题2:

a.g();

F()和g()不相互同步,因此可以完全并发执行。

,除非实现克()如下:

g() {
    synchronized(getClass()) {
        ...
    }
}

我发现这个模式也非常有用,当我想要实现的对象的不同实例之间的互斥(accesing外部资源时,其是需要的,例如)。

一个静态方法还具有相关联的对象。它属于Class.class文件在JDK工具包。当.class文件加载到RAM中,该Class.class创建它的一个实例称为模板对象。

如: - 当您尝试从现有的客户类对象像

Customer c = new Customer();

在Customer.class负载到RAM中。在那一刻Class.class在JDK工具包创建称为模板对象和载荷即Customer.class的Customer.class成模板object.Static成员成为该模板对象属性和方法的对象。

因此,一个静态方法或属性还具有一个目的

下面的示例更清楚地说明了类和对象锁之间的关系,希望下面的示例对其他人也有帮助:)

例如,我们有以下方法,一个获取类,另一个获取对象锁:

public class MultiThread {

    public static synchronized void staticLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }

    public synchronized void objLock() throws InterruptedException {
        for (int i = 0; i < 10; i++) {
            Thread.sleep(100);
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

所以,现在我们可以有以下场景:

  1. 当线程使用 相同的对象 尝试访问 objLock 或者 staticLock 方法同时(即两个线程都尝试访问相同的方法)

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  2. 当线程使用 相同的对象 尝试访问 staticLockobjLock 同时使用方法(尝试访问不同的方法)

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    
  3. 当线程使用 不同的对象 尝试访问 staticLock 方法

    Thread-0 0
    Thread-0 1
    Thread-0 2
    Thread-0 3
    Thread-0 4
    Thread-1 0
    Thread-1 1
    Thread-1 2
    Thread-1 3
    Thread-1 4
    
  4. 当线程使用 不同的对象 尝试访问 objLock 方法

    Thread-0 0
    Thread-1 0
    Thread-0 1
    Thread-1 1
    Thread-0 2
    Thread-1 2
    Thread-1 3
    Thread-0 3
    Thread-0 4
    Thread-1 4
    

有关那些谁不熟悉锁定类对象例如静态同步方法为字符串类其String.class而由在Java中关键字“this”表示对象的当前实例实例同步方法的锁。由于这两个对象是不同的,他们有不同的锁,以便当一个线程执行静态同步方法,在Java其他线程并不需要等待线程返回,而不是将收购独立的锁表示字节的.class文字和进入静态同步方法。

scroll top