У меня есть два потока, которые хотят к synchonize на том же объекте. Thead A
потребности смочь прервать Поток B
если определенное условие было выполнено. Вот некоторый псевдокод того, что/должны два потока, делают.
public void run()
{
while(true)
{
//Do stuff
synchronized(shared)
{
//Do more stuff
if(condition)
{
B.interrupt();
}
}
}
}
public void run()
{
while(true)
{
try
{
//Do stuff
synchronized(shared)
{
//Do more stuff
}
}
catch(InterruptedException e)
{
continue;
}
}
}
Вот ситуация, которую я не могу разрешить:
A
захватывает совместно используемый ресурс и делает некоторый материал.B
достигает синхронизируемого блока и ждет для A
выпускать его совместно используемый ресурс.A
, при выполнении материала, понятого, что Поток B не должен иметь совместно используемого ресурса и пытается прервать Поток B
. Но поток B
уже превзошел точки где InterruptedException
мог быть брошен.Мой вопрос, там любой способ прервать поток, в то время как он ожидает, чтобы быть synchronized
на чем-то?
Для таких вещей вам следует использовать классы из java.util.concurrent.locks
- у них гораздо больше возможностей, включая прерываемые блокировки.
Edit: Если вы не можете использовать эти классы, то посмотрите на ответ jkff - ваши требования могут быть выполнены с помощью механизма wait()
/notify()
, но в нем легко ввести тонкие ошибки.
Действительно, вы должны использовать блокировки или реализовать свои вещи с помощью Object. wait()
, Object.notify()
и Object.notifyAll()
(собственно, блокировки реализуются с их помощью). Не забывайте обрабатывать так называемые "ложные пробуждения" (wait()
может вернуться, даже если никто не вызывал notify()
или notifyAll()
, поэтому его всегда следует вызывать в цикле, проверяющем выполнение условия, которого вы ждете).
Нет, но ReentrantLock. lockInterruptibly()
ведет себя аналогично примитивной инструкции monitorenter
и может быть прерван.