【问题标题】:Threads access on Synchronized Block/Code Java同步块/代码 Java 上的线程访问
【发布时间】:2015-10-04 17:39:33
【问题描述】:

我正在阅读Synchronized 工作。示例如下:

public class Singleton{

private static volatile Singleton _instance;

public static Singleton getInstance(){
   if(_instance == null){
            synchronized(Singleton.class){
              if(_instance == null)
              _instance = new Singleton();
            }
   }
   return _instance;
}

假设两个线程AB正在访问getInstance();方法, 如果线程 Asynchronized 块中,则线程 B 将跳过该块并执行下一个块/语句,或者将等待/阻塞,直到线程 A 离开 synchronized 块。

第二个是什么,为什么synchronized参数中有Singleton.class,什么时候可以是null

下面的Statement是真的吗?

对象上有内在锁:

class A
{
   public synchronized void method1(){...}
   public synchronized void method2(){...}
}

如果线程A在method1,那么threadB就不能进入method2或者任何其他同步方法。

【问题讨论】:

  • 删除了我最初的答案。看起来 Java 的语义与 C# 不同,我将其翻译成这种情况。见stackoverflow.com/a/2462215/141172
  • @EricJ。你能确认这是真的吗? If thread A is in method1 then threadB cannot enter method2 or any other synchronized method .

标签: java multithreading synchronization


【解决方案1】:

1:线程B会等待,直到线程A释放同步对象上的锁并执行代码,之后它会获取同步对象上的锁。

2:Singleton.class 是代表该类的对象。您正在对其进行同步,因为您的 _instance-object 为空。

public synchronized void method1(){...}

在对象上同步,你调用那个方法,这意味着,如果你这样调用,2个线程将互相等待:

final A a = new A();
new Thread(new Runnable(){
    public void run(){
        a.method1();
    }
}).start();
a.method1();

但如果你在不同的对象上调用它,两个线程将并行执行:

A a = new A();
final A b = new A();
new Thread(new Runnable(){
    public void run(){
        b.method1();
    }
}).start();
a.method1();

最后一个问题:对了,线程B不会进入方法2,因为同步方法锁定了对象

顺便说一句。

public synchronized void method1(){...}

相当于:

public void method1(){
    synchronized(this){
        ...
    }
}

【讨论】:

  • 约翰尼你为什么使用final关键字?
  • @NewBie 如果没有 final,您将无法在 Runnable 中“看到”该变量。这样变量将存储在堆中而不是堆栈中,并且将在方法堆栈之外可用
  • 和 Johny 如你所说,Singleton.class 是对象,那么这句话的意思是什么? Only important thing to note here is that if object used to lock synchronized block of code, Singleton.class in below example is null then Java synchronized block will throw a NullPointerException. 那么我们每次都会遇到异常(创建实例)?此声明来自我给定的链接。
  • @NewBie no,Singleton.class 是一个对象,它代表类。它不是Singleton 类型的对象。在 Java 中,总是有 1 个对象,它代表类。例如。如果您要创建static synchronized 方法,该方法将锁定该类对象。而且不是null
  • 另一个不错的观点。你能给我关于类对象的链接吗?我想了解更多它的用途以及我们为什么需要它等等......或者你的意思是关于用于访问静态字段的对象?
【解决方案2】:

有关同步关键字的文档,请参阅 here

在方法上使用synchronized 将一次只允许一个线程访问该方法。所有其他线程将阻塞并排队等待执行。当你使用这个关键字时,实例对象被用作一个锁来同步执行。如果你在同一个对象上调用方法,一次只有一个线程可以持有锁,所以你的说法是正确的。

在方法上使用synchronized 关键字可能会降低性能,建议改用Java 并发API,请参阅here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    相关资源
    最近更新 更多