Инициализация класса и Dead-Lock в Java - PullRequest
0 голосов
/ 03 октября 2018

Следующий код приводит к initialization взаимозависимых классов deadlocks, когда два threads одновременно инициализируют эти classes.

Я не могу найти основную причину этой проблемы.

class A {
    static boolean x = B.b;
    static boolean a = true;
}

class B {
    static boolean b = true;
    static {
        if (A.a)
            throw new Error();
    }
}

public class Test {
    public static void main(String[] args) {
        Thread t1 = new Thread() {
            public void run() {
                new A();
            }
        };
        Thread t2 = new Thread() {
            public void run() {
                new B();
            }
        };
        t1.start();
        t2.start();
    }
}

Пожалуйста, помогите мне понять причину этой мертвой блокировки и как ее исправить.

1 Ответ

0 голосов
/ 03 октября 2018

Врезная блокировка возникает, когда два потока удерживают разные блокировки и пытаются захватить блокировку, удерживаемую другими.

В этом случае это происходит, когда

  • t1удерживает блокировку инициализации class A и пытается получить блокировку инициализации class B.

  • , в то время как t2 удерживает блокировку инициализации class B, и попытаться получитьблокировка инициализации class A.


Вы можете избежать условия гонки, выполнив t1 и t2 в следующем порядке:

t1.start();
t1.join();

t2.start();
t2.join();

Подробнее от jls :

Для каждого класса или интерфейса C существует уникальная блокировка инициализации LC.

....

Для каждого класса или интерфейса C существует уникальная блокировка инициализации LC.Отображение из C в LC оставлено на усмотрение реализации виртуальной машины Java.Тогда процедура инициализации C выглядит следующим образом:

  1. Синхронизация при блокировке инициализации, LC, для C. Это включает ожидание, пока текущий поток может получить LC.

  2. ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...