В какой момент блокировка действительно освобождается после вызова notify () - PullRequest
0 голосов
/ 14 октября 2018

У меня есть код, который я проверил, и я просто хочу знать, что мое понимание верно.У меня есть следующие два класса

public class WaitCheckWaiter implements Runnable
{

WaitCheck wc;

public WaitCheckWaiter( WaitCheck wc )
{
    this.wc = wc;
}

@Override
public void run()
{
    synchronized ( wc.strList )
    {
        wc.strList.add( "Added" );
        System.out.println( "Notify for others" );
        wc.strList.notifyAll();
        for ( int i = 0; i < 100; i++ )
        {
            System.out.println( i );
        }
        try
        {
            Thread.sleep( 5000 );
        }
        catch ( InterruptedException e )
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println( "Woke up" );
        System.out.println( "After Notifying" );
    }
    System.out.println( "After synch WaitCheckWaiter" );

}

}

, а затем этот ниже

public class WaitCheck implements Runnable{

WaitCheck wc;
List<String> strList = new ArrayList();

public static void main(String[] args) {
    WaitCheck wc = new WaitCheck();
    new Thread(wc).start();
    WaitCheckWaiter wcw = new WaitCheckWaiter(wc);
    new Thread(wcw).start();
}



@Override
public void run() {
    synchronized (strList) {
        if(strList.size() == 0)
        {
            try {
                System.out.println("Just Before wait..");
                strList.wait();
                System.out.println("Just after wait..");
                // printing the added value
                System.out.println("Value : "+strList.get(0));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        else
        {
            System.out.println("In else statement..!!");
        }
    }
    System.out.println("After synch WaitCheck");

}

}

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

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

Добавление к другому ответу из документа о Thread.sleep (...):

Поток не теряет права собственности ни на какие мониторы.

Это означает, что по крайней мере какОсновной принцип: никогда не следует вызывать Thread.sleep (...) до тех пор, пока все синхронизирующие блокировки все еще удерживаются.

0 голосов
/ 17 октября 2018

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

Когда поток вызывает o.wait(), его объект перемещается из «запущенного в данный момент»msgstr "очередь в очередь, которая содержит только те объекты, которые ожидают o.notify().Когда другой поток вызывает o.notify(), операционная система выбирает один поток из этой очереди и перемещает его в очередь потоков, ожидающих своей очереди, чтобы войти (или вернуться в) блок synchronized(o).

Этов значительной степени только вещь, которую o.notify() делает.Фактически, если очередь потоков, ожидающих o.notify(), пуста, то o.notify() вообще ничего не делает.

o.notifyAll() - то же самое, за исключением того, что вместо перемещения только одного потока,он перемещает все ожидающие потоки.

0 голосов
/ 14 октября 2018

Javadoc для метода Object.notifyAll довольно ясно по этой теме:

(текст, выделенный мной)

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

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

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