Что более твердо, синхронизируя 2 потока или 1 000 потоков?

На презентации Paul Tyma я нашел вопрос об интервью:

Что более твердо, синхронизируя 2 потока или синхронизируя 1 000 потоков?

С моей точки зрения конечно, синхронизация 1 000 потоков более трудна, но я не могу думать о серьезных основаниях для этого около, 'конечно'. Но так как это - вопрос об интервью, может быть, я неправ (вопросы об интервью должны быть хитрыми, не так ли?).

11
задан claws 29 July 2010 в 14:02
поделиться

14 ответов

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

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

14
ответ дан 3 December 2019 в 00:41
поделиться

Я согласен с теми, кто утверждает, что «это зависит от обстоятельств». Если нити идентичны, то такой большой разницы между 2 и 1000 нитками быть не может. Однако, если есть несколько ресурсов, которым требуется взаимоисключающий доступ (синхронизированный в терминах Java), то вероятность взаимоблокировок может увеличиваться с увеличением числа потоков.

1
ответ дан 3 December 2019 в 00:41
поделиться

Почему синхронизировать 1000 потоков сложнее, чем синхронизировать 2 потока?

Единственный код, который будет добавлен, - это порождение дополнительных потоков.

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

3
ответ дан 3 December 2019 в 00:41
поделиться

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

Сценарий может быть таким же простым, как один фоновый рабочий поток, которого ожидает передний план при отображении индикатора выполнения. Или он может создать 1000 потоков и просто дождаться их завершения, прежде чем делать что-то еще.

В качестве альтернативы, если к разделяемым ресурсам обращаются всего 2 потока, концепции остаются теми же. Вы должны быть очень осторожны с проблемами параллелизма и стратегиями блокировки, будь то 2 или 1000. Независимо от того, сколько потоков более одного, вы не можете гарантировать, что что-то еще не пытается одновременно читать или записывать в тот же ресурс, что и вы. .

1
ответ дан 3 December 2019 в 00:41
поделиться

Вы можете доказать, что правильно синхронизировать 2 потока на самом деле сложнее, чем сделать это для 1000, потому что, если у вас есть состояние гонки, оно обычно проявляется очень быстро с 1000 потоков, но не только с 2.

Но с другой стороны, синхронизировать 1000 потоков без проблем, связанных с конфликтами блокировок, намного сложнее, чем когда их всего 2.

Настоящий ответ таков: «синхронизировать потоки сложно по-разному, точка»

38
ответ дан 3 December 2019 в 00:41
поделиться

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

Надеюсь, что это помогло

0
ответ дан 3 December 2019 в 00:41
поделиться

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

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

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

2
ответ дан 3 December 2019 в 00:41
поделиться

Думаю, ответ состоит в том, что после синхронизации двух потоков все остальные 998 также будут синхронизированы

3
ответ дан 3 December 2019 в 00:41
поделиться

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

4
ответ дан 3 December 2019 в 00:41
поделиться

Если вы используете такой язык программирования, как Scala, с паттерном проектирования Actors, то вам не нужно ничего синхронизировать. http://www.scala-lang.org/node/242

Другой вариант (в Java) - использовать механизм сравнения и подкачки/сброса http://en.wikipedia.org/wiki/Compare-and-swap, так что вам не придется синхронизировать потоки, поскольку они являются атомарными переменными, которые вы сравниваете и читаете (неблокирующими), и только блокируют/ожидают при записи, что может дать огромный прирост производительности, основанный на вашем решении

.
0
ответ дан 3 December 2019 в 00:41
поделиться

Объекты синхронизируются, а не потоки. Создание синхронизированного метода или блока кода предотвращает одновременное выполнение области несколькими потоками, поэтому не имеет значения, есть ли 2, 1000 или 1000000 потоков.

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

0
ответ дан 3 December 2019 в 00:41
поделиться

Это зависит от того, что означает «проще». Сложность конструкции / запорных механизмов примерно такая же.

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

3
ответ дан 3 December 2019 в 00:41
поделиться

У меня два ответа.

  1. СЛУЧАЙ 1: Использование существующих ресурсов: Синхронизация 2 потоков такая же сложность, как и синхронизация 1000 потоков, поскольку существующие создаются для синхронизации произвольного количества потоков.
  2. СЛУЧАЙ 2: Реализация с нуля Кажется очевидным, что если бы вам пришлось реализовать систему синхронизации с нуля, было бы проще построить двухпоточную систему.
3
ответ дан 3 December 2019 в 00:41
поделиться

Пробежавшись по вашим ответам, я обнаружил несколько интересных хардтов. Я думаю, на собеседовании это важнее, чем ответ: обращение, жесткость.

1
ответ дан 3 December 2019 в 00:41
поделиться
Другие вопросы по тегам:

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