Какой из них лучше для производительности, чтобы проверить другие потоки логические в Java - PullRequest
4 голосов
/ 13 февраля 2012
while(!anotherThread.isDone());

или

while(!anotherThread.isDone())
    Thread.sleep(5);

Ответы [ 8 ]

6 голосов
/ 13 февраля 2012

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

anotherThread.join()

(Возможно, вы захотите указать время ожидания при соединении).

Вы определенно не должны сжиматься, как это делает ваш первый фрагмент ... и спать в течение 5 мс едва лучше.

Если вы не можете использовать join (например, вы ожидаете завершения задачи, а не целого потока), вам следует взглянуть на пакет java.util.concurrent - скорее всего, есть что-то, что будет соответствовать вашим потребностям.

5 голосов
/ 13 февраля 2012

ИМХО, избегайте использования такой логики вообще. Вместо этого, возможно, реализовать какую-то систему уведомлений, используя прослушиватели изменения свойств.

3 голосов
/ 13 февраля 2012

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

Обычно, когда поток ожидает событие, которое зависит от другого потока, лучше:

  1. Используйте механизм блокировки (т. Е. Соединение, условная переменная и т. Д.) Или
  2. Занятое вращение без сна или
  3. Занято вращение со сном?

Теперь посмотрим, каковы последствия для каждого случая:

  1. В этом случае используется блокирующий вызовбудет эффективно удалять поток из процессора и не планировать его снова, пока не произойдет ожидаемое событие.Хорошо для использования ресурсов (в противном случае поток будет тратить циклы ЦП), но не очень эффективно, если событие может происходить очень часто и с небольшими интервалами (т. Е. Переключение контекста занимает гораздо больше времени, чем время, которое требуется для возникновения события).Обычно хорошо, когда событие произойдет в конце концов, но вы не знаете, как скоро.
  2. В случае два, вы заняты вращением, то есть вы активно используете процессор, не выполняя полезную работу.Это противоположно случаю 1: это полезно, когда ожидается, что событие произойдет очень очень скоро , но в противном случае может излишне занять ЦП.
  3. Этот случай является своего родавыкл.Вы заняты вращением, но в то же время позволяете другим потокам работать, отказываясь от процессора.Это обычно используется, когда вы не хотите насыщать процессор, но событие должно произойти в ближайшее время, и вы хотите быть уверены, что вы все еще будете там в почти в реальном времени , чтобы поймать его, когда онопроисходит.
3 голосов
/ 13 февраля 2012

Я бы рекомендовал использовать механизм ожидания / уведомления, встроенный во все объекты Java (или использовать новый код блокировки в Java 5 ).

Поток 1 (ожиданиедля темы 2)

while(!thread2.isDone()) {
  synchronize(thread2.lockObject) {
    thread2.lockObject.wait();
  }
}

Тема 2

// finish work, set isDone=true, notify T1
thread2.lockObject.notify();

'lockObject' - просто обычный объект (Object lockObject = new Object ()) - все объекты Java поддерживают вызовы wait / notify.

После этого последнего вызова notify () Thread1 проснется, достигнет вершины времени и увидит, что T2 теперь завершен,и продолжить выполнение.

Вы должны учитывать исключения прерываний и тому подобное, но использование wait / notify чрезвычайно полезно для подобных сценариев.

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

ADDENDUM

Я вижу много комментариевГоворя об использовании join - если ожидающий поток выполнения завершится, тогда да, используйте jойн.Если у вас есть два параллельных потока, которые выполняются постоянно (например, поток производителя и потребитель), и они не «завершаются», они просто работают в режиме блокировки друг с другом, тогда вы можете использовать парадигму ожидания / уведомления Iпредоставлено выше.

1 голос
/ 13 февраля 2012

Второй.

Лучше использовать метод join() потока, чтобы заблокировать текущий поток до его завершения:).

EDIT:

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

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

0 голосов
/ 13 февраля 2012

Ни один, вместо этого используйте join():

anotherThread.join();
// anotherThread has finished executing.
0 голосов
/ 13 февраля 2012

Второй лучше первого, но ни один не очень хорош.Вы должны использовать anotherThread.join() (или anotherThread.join(timeout)).

0 голосов
/ 13 февраля 2012

Рассматривали ли вы: anotherThread.join()? Это приведет к тому, что текущий будет «припаркован» без каких-либо накладных расходов, пока другой не прекратит работу.

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