我在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 共享此锁的方式是什么?
由于
答案 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}}引用两种方法的相同实例(对象锁定)