锁定类的静态成员

时间:2012-04-19 22:27:14

标签: java multithreading concurrency locking deadlock

根据我的理解,下面这段代码会导致死锁。 原因是,当线程t1锁定静态对象firstData时,他已经获得了对类的锁定。因此,当他试图锁定另一个静态对象secondData时,请求应该阻塞。

但是,程序运行正常并打印*** Successfully acquired both the locks

关于锁定我遗漏的静态物体有什么用?

public class Deadlock {
    public static void main(String[] args) {

        Thread t1 = new Thread(new DeadlockRunnable());
        t1.start();
    }
} 

 class DeadlockRunnable implements Runnable {
    static  Object firstData = new Object();
    static  Object secondData = new Object();

    public void run() {
        synchronized(firstData) {
            synchronized(secondData) {
                System.out.println("*** Successfully acquired both the locks");
            }
        }
    }

}

对于那些回答说锁是对象而不是课堂的人,请看一下this

2 个答案:

答案 0 :(得分:14)

首先,你在这里犯了错误:

  

原因是,当线程t1锁定静态对象firstData时,他已经获得了对该类的锁定。

锁定静态对象仅锁定该对象,而不是类。您正在锁定两个单独的对象。

question you refered to约为synchronized methods而不是synchronized statements。这两个相关结构的工作方式略有不同。


其次,即使您锁定了同一个对象,您的代码仍然不会死锁(ideone)。内部锁是可重入。这意味着如果一个线程尝试两次使用相同的锁,它就不会死锁。

  

可重入同步

     

回想一下,线程无法获取另一个线程拥有的锁。但是一个线程可以获得它已经拥有的锁。允许线程多次获取相同的锁可启用重入同步。这描述了一种情况,其中同步代码直接或间接地调用也包含同步代码的方法,并且两组代码使用相同的锁。如果没有可重入同步,同步代码必须采取许多额外的预防措施,以避免线程导致自身阻塞。

Source

答案 1 :(得分:1)

“当线程t1锁定静态对象firstData时,他已经获得了对类的锁定” 不确定你为什么这么认为。 t1获取firstData上的锁,而不是包含类。代码中没有可能的死锁。

修改
在您的评论之后,链接是关于这两个声明之间的区别:

public synchronized method() // lock on the instance (this)
public static synchronized method() // lock on the class (Myclass.class)

但是没有死锁的链接。