0

我在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会在单例对象上获得锁。但是另一个线程(比如thread-2)想要进入,method2()然后它将进入而不等待 thread-1释放锁。thread-1thread-2如何共享此锁?

谢谢

4

5 回答 5

1

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

它不会。

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

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

这个

于 2013-03-15T11:36:29.180 回答
0

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

例如

Object lock = new Object;
public void method1() {
    synchronized(lock) {
      // do stuff here
    }
}
于 2013-03-15T11:36:32.940 回答
0

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

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

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

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

public void method2 {
    synchronized(object2) {
    ....
    }
}
于 2013-03-15T11:42:21.700 回答
0

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

于 2013-03-15T11:42:44.647 回答
0

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

虽然 thread1method1()使用 A 的实例同步执行,但 thread2 将等待它执行method2(),这也使用 A 的同一实例同步(因为它是Singleton

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

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

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

考虑到这一点,您可以看到两种方法都this引用同一个实例(对象锁)

于 2013-03-15T11:44:07.160 回答