Может ли поток вызвать wait () для двух блокировок одновременно в Java (6) - PullRequest
0 голосов
/ 17 июня 2010

Я только что возился с потоками в Java, чтобы разобраться с ними (кажется, это лучший способ сделать это) и теперь понимаю, что происходит с синхронизацией, ожиданием () и уведомлением ().

Мне любопытно, есть ли способ ожидания () на двух ресурсах одновременно.Я думаю, что следующее не совсем то, о чем я думаю ( edit : обратите внимание, что обычные циклы while были исключены из этого примера, чтобы сосредоточиться только на освобождении двух ресурсов ):

synchronized(token1) {
    synchronized(token2) {
        token1.wait();
        token2.wait(); //won't run until token1 is returned
        System.out.println("I got both tokens back");
    }
}

В этом (очень надуманном) случае token2 будет удерживаться до тех пор, пока не будет возвращен token1, затем token1 будет удерживаться до тех пор, пока не будет возвращен token2.Цель состоит в том, чтобы освободить как token1, так и token2, а затем возобновить, когда оба будут доступны (обратите внимание, что перемещение token1.wait () за пределы внутреннего синхронизированного цикла - это не то, к чему я стремлюсь.

Проверка цикламогут ли оба быть более подходящими для достижения такого поведения (будет ли это приближаться к идее двойной проверки блокировки?), но потребуются ли дополнительные ресурсы - я не ищу окончательного решения, так как это просто для удовлетворения моеголюбопытство.

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

Ответы [ 2 ]

2 голосов
/ 17 июня 2010

Пример не включает условие, при котором будет выполняться ожидание.Как правило, ожидание будет происходить только до тех пор, пока условие не будет выполнено.Как правило, я думаю, что можно выполнить то, что вы пытаетесь сделать, с помощью одной блокировки / ожидания и абстрагирования 'token1 и token2' в условную логику.

Например,

synchronized(object) {
   while ((!token1ConditionMet) && (!token2ConditionMet)) {
       wait();
   }
} 
2 голосов
/ 17 июня 2010

Нет, не со стандартной блокировкой Java.Хотя я предполагаю, что вы могли бы создать такую ​​блокировку.

wait должен вызываться в цикле while (wait может внезапно пробуждаться, и в большинстве случаев вы все равно захотите цикл).Так что какой-то флаг имеет больше смысла.

...