одновременные обновления на массиве в Java - PullRequest
3 голосов
/ 14 апреля 2011

в Java, у меня большой массив строк.

У меня один поток делает что-то вроде этого:

for (int i=0;i<10000;i++) array[i] = getSomeValue();

У меня есть другой поток, который делает что-то вроде этого:

for (int i=10000;i<20000;i++) array[i] = getSomeValue();

и другой поток делает:

for (int i=20000;i<30000;i++) array[i] = getSomeValue();

и так далее.

Должен ли я сделать что-то особенное, чтобы выполнить эту операцию?

это будет работать?

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

Я работаю на 64-битной машине с 16 процессорами и всеми этими модными штуками.

Ответы [ 6 ]

8 голосов
/ 14 апреля 2011

Ваш код будет работать нормально.

Различные части массива не зависят друг от друга.

spec говорит:

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

1 голос
/ 14 апреля 2011

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

1 голос
/ 14 апреля 2011

Это должно работать нормально. Однако, если вы хотите быть уверенным, что это безопасно, вы можете заполнить разные массивы в каждом потоке, а затем System.arraycopy () их в один большой массив.

0 голосов
/ 26 сентября 2016

С Java 8 это стало намного проще:

Arrays.parallelSetAll(array, i -> getSomeValue());

Это также должно решить проблемы видимости, упомянутые в других ответах и ​​комментариях.

0 голосов
/ 14 апреля 2011

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

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

0 голосов
/ 14 апреля 2011

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

Будет ли он на самом деле быстрее, зависит от настроек вашего оборудования и реализации потоков.

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