Реализация глобальной блокировки в Java - PullRequest
2 голосов
/ 07 июня 2009

У меня относительно простой (возможно, глупый) вопрос относительно синхронизации в Java.

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

Есть ли причудливый способ сделать это в Java без переписывания всего текущего кода синхронизации?

Например,

Тема t1

synchronized (o1)
{
    synchronized (o2)
    {
        // ...
    }
}

Тема t2

synchronized (global_lock)
{
    // ...
}

Когда поток t2 находится внутри синхронизированного блока, потоку t1 нельзя разрешать получать блокировки на o1 и o2.

Большое спасибо если

Ответы [ 3 ]

11 голосов
/ 07 июня 2009
  1. Это невозможно;
  2. Это действительно плохая идея (извините).

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

Обычно хорошей идеей, если вам нужно приобрести два замка, всегда иметь заранее определенный порядок:

synchronized(LOCK1) {
  synchronized(LOCK2) {

  }
}

Но для глобальной блокировки потребуется какой-то протокол - глобальный заказ на приобретение - для всех блокировок. И это может быть невозможно вообще. Большинство блокировок защищают определенные, автономные, критические секции. Они не будут знать, что кто-то «выдернет» их и приобретет, и поэтому не будут написаны, чтобы справиться с этой ситуацией.

Так что это невозможно, и вы должны быть счастливы, что это не так. Хотя это кажется легким выходом, это принесет много боли.

0 голосов
/ 07 июня 2009

Оставляя в стороне ужас от того, что вы предлагаете, вы можете рассмотреть возможность использования Аспектно-ориентированного программирования (AOP) для «добавления» дополнительной синхронизации / блокировки в код во время выполнения. Вы должны быть в состоянии сделать это без написания источника.

Существует множество вариантов AOP, включая AspectJ и Spring AOP, которые могут подходить в зависимости от вашей среды.

0 голосов
/ 07 июня 2009

Единственно возможный способ сделать это - фактически проанализировать / изменить / сохранить (автоматически) весь код. Я недавно сделал что-то подобное для проекта, и он работал довольно хорошо. Мы можем поговорить больше, если вам интересно.

...