Возможен ли поток для самой тупиковой блокировки?

Возможно ли, чтобы поток в Java технически заблокировал сам себя?

Меня спросили об этом на собеседовании некоторое время назад, и он ответил, что это невозможно, но интервьюер сказал мне, что это так. К сожалению, я не смог получить его метод о том, как добиться этого тупика.

Это заставило меня задуматься, и единственная ситуация, о которой я могу подумать, - это то, где вы можете это сделать, когда у вас есть процесс сервера RMI, который содержит метод, который вызывает себя. Строка кода, вызывающая метод, помещается в синхронизированный блок.

Это вообще возможно или неправильный интервьюер?

Исходный код, о котором я думал, был по этим направлениям (где testDeadlock выполняется в RMI серверный процесс)

public boolean testDeadlock () throws RemoteException {
    synchronized (this) {
        //Call testDeadlock via RMI loopback            
    }
}
59
задан Balder 12 January 2015 в 14:42
поделиться

13 ответов

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

0
ответ дан 24 November 2019 в 18:20
поделиться

Возможно, он имел в виду сам LOCK , это определенно слишком просто:

synchronized( this )
{
    wait( );
}
10
ответ дан 24 November 2019 в 18:20
поделиться

Вот способ блокировки самого потока.

public class DeadlockMe
{
    public static void main(String[] args)
    {
        DeadlockThing foo = new DeadlockThing();
        synchronized(foo)
        {
            try
            {
                foo.wait();
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

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

0
ответ дан 24 November 2019 в 18:20
поделиться

Хотя я не использовал Java, я раньше блокировал однопоточное приложение. IIRC: Routine A заблокировал фрагмент данных для его обновления. Подпрограмма B также заблокировала тот же фрагмент данных, чтобы обновить его. Из-за изменений требований А позвонил Б. Упс.

Конечно, это была обычная ошибка разработки, которую я обнаружил при первой попытке запустить код, но она сама заблокировалась. Я думаю, что взаимоблокировки такого типа возможны на любом языке, поддерживающем файловую систему.

2
ответ дан 24 November 2019 в 18:20
поделиться

Итак, исходя из определения:

Тупиковая ситуация - это ситуация, в которой два или более конкурирующих действия ожидают завершения друг друга.

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

Если кто-то не объяснит мне, как один поток может одновременно ожидать завершения двух действий?

ОБНОВЛЕНИЕ: Единственная возможная ситуация, о которой я могу думать, это своего рода перекачка сообщений, когда поток обрабатывает сообщение, которое просит его ждать неопределенно долго, пока что-то не произойдет, тогда как на самом деле это что-то будет обработано другим сообщением в насосе сообщений.

Этот (невероятно надуманный) сценарий технически можно назвать тупиком.

51
ответ дан 24 November 2019 в 18:20
поделиться

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

Так что я не думаю, что это возможно.

0
ответ дан 24 November 2019 в 18:20
поделиться

Если растянуть определение термина deadlock: один поток может оказаться заблокированным на нереентерабельной блокировке, которую он взял ранее.

0
ответ дан 24 November 2019 в 18:20
поделиться

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

0
ответ дан 24 November 2019 в 18:20
поделиться

Нет, потому что Java реализует reentrancy. Но, пожалуйста, не надо так смешивать параллелизм и RMI. Синхронизация в заглушках - это нечто совершенно иное, чем удаленные объекты, которые внутренне синхронизированы.

1
ответ дан 24 November 2019 в 18:20
поделиться

Это зависит от того, что именно вы подразумеваете под «тупиком». Например, вы могли бы легко wait () на мониторе, на котором ничто никогда не будет пульсировать ... но я не думаю, что я бы назвал это тупиком как таковой.

Если подумать о ваших строках «метод, который вызывает сам себя», если ваш сервер запускает только определенное количество потоков, все они могут быть заняты ожиданием ответов от одного и того же сервера, если это имеет значение. (Самый простой пример: сервер использует только один поток для обработки. Если вы напишете обработчик запроса, который обращается к тому же серверу, он будет ждать, пока заблокированный поток закончит обработку запроса, прежде чем он сможет обработать тот же запрос ...) На самом деле это не тупик типа «синхронизированный блок», но это определенно опасность, о которой следует знать.

РЕДАКТИРОВАТЬ: Чтобы применить этот ответ к определению в других, конкурирующими действиями здесь будут «завершить текущий запрос» и «обработать новый запрос». Каждое действие ожидает выполнения другого.

19
ответ дан 24 November 2019 в 18:20
поделиться

Возможно, интервьюер имел в виду:

Thread.currentThread().join();

Однако я бы сказал, что это не считается тупиком.

7
ответ дан 24 November 2019 в 18:20
поделиться

Переход от блокировки чтения к блокировке записи (попытка получить блокировку записи, удерживая блокировку чтения) приводит к тому, что поток полностью блокируется. Является ли это тупиком? Судите сами... Но это самый простой способ создать такой эффект с одним потоком.

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html

6
ответ дан 24 November 2019 в 18:20
поделиться

Согласно Википедии, «Тупик - это ситуация, в которой два или более конкурирующих действия ждут завершения друг друга, и, таким образом, ни одно из них никогда не завершится».

... »В информатика, тупик Коффмана относится к определенному состоянию, когда два или более процесса ждут друг друга, чтобы освободить ресурс, или более двух процессов ожидают ресурсов в кольцевой цепочке ».

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

5
ответ дан 24 November 2019 в 18:20
поделиться
Другие вопросы по тегам:

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