在多线程中锁定对象

时间:2013-03-15 11:32:34

标签: java

我在java中的对象锁定中有一个问题。 防爆。代码:

public class A 
{
    private static A a = null; // singleton instance

    private A()
    {

    }

    public static synchronized A getInst()
    {
        if (a == null)
        {
            a = new A();
        }
        return a;
    }

    public synchronized void method1()
    {
        //some action
    }

    public synchronized void method2()
    {
        //some action
    }
}

当一个帖子(比如 thread-1 )在method1()内工作时, thread-1 在单例上获取 lock 宾语。但是另一个线程(比如 thread-2 )想要输入method2()然后它将进入而不等待 thread-1 释放锁。 thread-1 thread-2 共享此锁的方式是什么?

由于

5 个答案:

答案 0 :(得分:1)

  

但是另一个线程(比如thread-2)想要输入method2然后它将进入而不等待thread-1释放锁。

不会。

有一次,只有一个线程可以获取对象的锁定。

因此,除非thread-1释放锁定,否则thread-2无法执行method2

阅读this

答案 1 :(得分:0)

您应该使用特定锁定对象的synchronized块而不是同步方法。 在这种情况下,如果您不需要同步整个方法,也很容易阻止需要锁定的方法的特定部分,这可能会加速多线程访问。

e.g。

Object lock = new Object;
public void method1() {
    synchronized(lock) {
      // do stuff here
    }
}

答案 2 :(得分:0)

在单例类中,只有一个实例可用。因此,当调用synchronized方法时,它将锁定该单个实例。如果存在多个同步方法,则一次只执行一个方法。其他需要等待以前的方法来释放锁。所以基本上只有一个线程存在于这个单例类中。

如果您希望其他方法因其他方法锁定而不受影响,请在单例类中使用带有对象锁定的synchronized块。

private final Object object1 = new Object();
private final Object object2 = new Object();

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

public void method2 {
    synchronized(object2) {
    ....
    }
}

答案 3 :(得分:0)

两个同步方法都是实例方法,因此,如果所有这些方法都引用同一个实例,多个线程将无法同时访问它们EM>。在你的情况下这是真的,因为你只有一个类的实例( singleton 模式),因此如果一个线程正在访问method1(),那么其他线程访问{{1}将进入等待状态,直到thread1释放锁或完全执行method2()

答案 4 :(得分:0)

  

但另一个线程(比如thread-2)想要输入method2   然后它将进入而不等待thread-1释放锁。

当thread1执行使用A的实例进行同步的method1()时,thread2将在执行method2()之前等待,该public void method1() { synchronized (this) { //some action } } public void method2() { synchronized (this) { //some action } } 也使用相同的实例进行同步的A(因为它是 Singleton

您可以将其视为已同步的代码块关键部分),而不是同步方法,例如:

this

考虑到这一点,您可以看到{{1}}引用两种方法的相同实例(对象锁定)