【问题标题】:Locking static members of a class锁定类的静态成员
【发布时间】:2012-05-01 12:54:57
【问题描述】:

根据我的理解,下面这段代码应该会导致死锁。 原因是,当线程 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

【问题讨论】:

    标签: java multithreading concurrency locking deadlock


    【解决方案1】:

    首先,你这里有一个错误:

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

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

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


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

    重入同步

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

    Source

    【讨论】:

    • 以下链接让我相信:stackoverflow.com/questions/437620/…
    • 我同意@KirkWoll。但我有一个问题。那么这是否意味着一个线程可以同时锁定多个静态对象?
    • @KirkWoll 仅适用于可重入锁
    • @John,您是否建议您可以在某些情况下使用单线程产生死锁?请详细说明。
    • @noMAD 假设是绝对正确的。它实际上有一个名字。它称为锁粗化。该优化内置于 Java 的 JIT 中。
    【解决方案2】:

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

    编辑
    根据您的评论,链接是关于这两个声明之间的区别:

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

    但是没有死锁的链接。

    【讨论】:

    • 以下链接让我相信stackoverflow.com/questions/437620/…
    • @assylias :您能否解释一下当 t1 获得对“firstData”(静态字段)的锁定时,什么对象被锁定...您的意思是只有对象 firstData 被锁定吗? ...无论是类还是容器 DeadlockRunnable 对象?
    • @tm.sauron 是的 - 锁绑定到特定对象,在本例中为 firstDatasecondData - 封闭类 DeadlockRunnable 在这里除了代码容器之外没有其他作用。 ..
    猜你喜欢
    • 1970-01-01
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 2017-10-20
    • 2012-04-13
    • 1970-01-01
    相关资源
    最近更新 更多