Как я могу прервать синхронизированного оператора в Java?

У меня есть два потока, которые хотят к synchonize на том же объекте. Thead A потребности смочь прервать Поток B если определенное условие было выполнено. Вот некоторый псевдокод того, что/должны два потока, делают.

A:

public void run()
{
    while(true)
    {
        //Do stuff
        synchronized(shared)
        {
            //Do more stuff
            if(condition)
            {
                B.interrupt();
            }
        }
    }
}

B:

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 на чем-то?

7
задан Eric 17 April 2017 в 18:33
поделиться

3 ответа

Для таких вещей вам следует использовать классы из java.util.concurrent.locks - у них гораздо больше возможностей, включая прерываемые блокировки.

Edit: Если вы не можете использовать эти классы, то посмотрите на ответ jkff - ваши требования могут быть выполнены с помощью механизма wait()/notify(), но в нем легко ввести тонкие ошибки.

5
ответ дан 7 December 2019 в 03:15
поделиться

Действительно, вы должны использовать блокировки или реализовать свои вещи с помощью Object. wait(), Object.notify() и Object.notifyAll() (собственно, блокировки реализуются с их помощью). Не забывайте обрабатывать так называемые "ложные пробуждения" (wait() может вернуться, даже если никто не вызывал notify() или notifyAll(), поэтому его всегда следует вызывать в цикле, проверяющем выполнение условия, которого вы ждете).

3
ответ дан 7 December 2019 в 03:15
поделиться

Нет, но ReentrantLock. lockInterruptibly() ведет себя аналогично примитивной инструкции monitorenter и может быть прерван.

1
ответ дан 7 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: