может завершиться успешно, когда мы используем только метод wait () и не уведомляем () [duplicate]

вы можете использовать встроенную функцию list ():

newlist=list(oldlist)

Я думаю, этот код вам поможет.

6
задан bcsb1001 7 September 2014 в 16:22
поделиться

2 ответа

Вы ожидаете на Thread - и если большинство объектов не оповещены , объект Thread уведомляется, когда поток завершается. Он где-то документирован (я ищу его ...), что вы должны not использовать wait / notify на объектах Thread, поскольку это сделано внутренне.

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

private final Object lock = new Object();

(В общем, однако, чище использовать некоторые абстракции более высокого уровня, предоставляемые java.util.concurrent, если вы можете. Как отмечено в комментариях, это также неплохо реализовать Runnable, а не расширять Thread самостоятельно.)

10
ответ дан Jon Skeet 21 August 2018 в 04:21
поделиться
  • 1
    Ряд методов в потоке синхронизируется на этом объекте и использует wait / notify, поэтому следует ожидать побочных пробуждений. Его также хорошая практика не продлить Thread, а использовать Runnable, который обернут Thread. Это также позволило бы избежать этой проблемы. – Peter Lawrey 27 January 2012 в 10:31
  • 2
    @PeterLawrey: До тех пор, пока OP тогда использовал wait / notify на runnable, а не в потоке :) Я все же предпочитаю иметь "тупой" объект, который я лично не раскрываю где-либо . – Jon Skeet 27 January 2012 в 10:34
  • 3
    В идеале, вы хотите, чтобы оба, так как вы не знаете, как код может быть изменен в будущем. ИМХО, обладающее множеством стратегий, которые лучше всего защищают ваш код. – Peter Lawrey 27 January 2012 в 10:38
  • 4
    @PeterLawrey: Верно, я с тобой. Полностью согласен :) – Jon Skeet 27 January 2012 в 11:04
  • 5

JavaDoc для wait дает ответ: возможны побочные пробуждения. Это означает, что JVM имеет право закончить вызов wait всякий раз, когда захочет.

Документация даже дает вам решение, если вы этого не хотите (что, вероятно, всегда так): поставьте вызовите wait в цикле и проверьте, стало ли ожиданное условие после каждого пробуждения.

8
ответ дан Philipp Wendler 21 August 2018 в 04:21
поделиться
  • 1
    @Boris В случае ложного пробуждения нет никаких исключений. InterruptedException вызывается только тогда, когда поток прерывается. – Philipp Wendler 27 January 2012 в 10:19
  • 2
    Я сомневаюсь, что это на самом деле ложное пробуждение - я считаю, что это поведение ожидания на Thread в частности; он будет уведомляться, когда поток завершается. Это не паразитный в обычном смысле. – Jon Skeet 27 January 2012 в 10:28
  • 3
    Даже без ложных пробуждений, с шаблоном монитора (или любым из его вариантов) вы всегда хотите зацикливать и проверить условия. Это предотвращает проблемы, если вы позже добавите другое условие (мониторы java и C # используют один объект как блокировку, так и переменную условия, поэтому вы не можете использовать одну переменную условия для каждого условия). Это также мешает вам выполнять процедуру, если условие было выполнено, но первый поток, ожидающий того же объекта, пошел первым, и теперь условие перестало быть истинным. – Kevin Cathcart 27 January 2012 в 18:57
Другие вопросы по тегам:

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