简体   繁体   English

锁定类的静态成员

[英]Locking static members of a class

According to my understanding, the following piece of code should result in a deadlock. 根据我的理解,以下代码段将导致死锁。 The reason being, when thread t1 locks static object firstData, he has acquired a lock on the class. 原因是,当线程t1锁定静态对象firstData时,他已经获得了对该类的锁定。 So, when he tries to lock another static object secondData, the request should block. 因此,当他尝试锁定另一个静态对象secondData时,请求将被阻止。

However, the program runs fine and prints *** Successfully acquired both the locks 但是,该程序可以正常运行并打印*** Successfully acquired both the locks

What is it about locking static objects that im missing here? 锁定此处缺少的静态对象是什么?

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");
            }
        }
    }

}

For all those who answered that the locks are on object, instead of class, please take a look at this 对于那些谁回答了锁的对象,而不是类,请看看这个

Firstly, you have a mistake here: 首先,您在这里有一个错误:

The reason being, when thread t1 locks static object firstData, he has acquired a lock on the class. 原因是,当线程t1锁定静态对象firstData时,他已经获得了对该类的锁定。

Locking a static object locks only that object, not the class. 锁定静态对象只会锁定该对象,而不会锁定类。 You are locking two separate objects. 您正在锁定两个单独的对象。

The question you refered to is about synchronized methods not synchronized statements . 您提到问题是关于同步方法而不是同步语句 These two related constructs work in slightly different ways. 这两个相关的构造工作方式略有不同。


Secondly, even if you were locking on the same object, your code would still not deadlock ( ideone ). 其次,即使您锁定了同一对象,您的代码仍不会死锁( ideone )。 Intrinsic locks are reentrant . 内部锁是可重入的 This means that a thread does not deadlock itself if it tries to take the same lock twice. 这意味着,如果一个线程尝试进行两次相同的锁定,它本身不会死锁。

Reentrant Synchronization 重入同步

Recall that a thread cannot acquire a lock owned by another thread. 回想一下,一个线程无法获取另一个线程拥有的锁。 But a thread can acquire a lock that it already owns. 但是线程可以获取它已经拥有的锁。 Allowing a thread to acquire the same lock more than once enables reentrant synchronization. 允许一个线程多次获取相同的锁将启用重入同步。 This describes a situation where synchronized code, directly or indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock. 这描述了一种情况,其中同步代码直接或间接调用一个也包含同步代码的方法,并且两组代码使用相同的锁。 Without reentrant synchronization, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block. 如果没有可重入同步,则同步代码将不得不采取许多其他预防措施,以避免线程导致自身阻塞。

Source 资源

"when thread t1 locks static object firstData, he has acquired a lock on the class" “当线程t1锁定静态对象firstData时,他已获取该类的锁”
Not sure why you think so. 不知道为什么会这样。 t1 acquires a lock on firstData, not on the containing class. t1获得对firstData的锁定,而不是对包含类的锁定。 There is no possible deadlock in your code as it is. 在您的代码中没有可能的死锁。

EDIT 编辑
Following your comment, the link is about the difference between those 2 declarations: 在您发表评论之后,该链接是关于这两个声明之间的区别的:

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

But there is no link with deadlocks. 但是,死锁没有联系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM