2017-02-06 21 views
-3

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

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

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

+2

Используйте поисковую систему на ваш выбор, чтобы найти: 'java synchronized'. Но если вы не знаете об этом уже, ваше многопоточное приложение будет иметь трудное время. –

+0

Какова ваша идея или мысли о приближении к ней? – RamPrakash

+0

вы пробовали? он должен бросить ConcurrentModificationException! – StackFlowed

ответ

1

Ваши варианты - либо работать с синхронизацией, либо использовать реализацию, представленную в пакете java.util.concurrent. Вам также необходимо ознакомиться с этой проблемой. Вы задаете очень фундаментальный и классический вопрос, и есть много информации по этому issue.But вот ваши основные варианты:

  1. Использования синхронизации - Вера дорогой производительности мудрые, но абсолютно пуленепробиваемый. прочитайте в synchronized термин или ознакомьтесь с интерфейсом Lock и его реализациями. Также смотрите около Semaphore класс. Обратите внимание, что этот вариант создаст очень серьезную горло бутылки в вашей производительности.
  2. Как говорится в одном из комментариев, используйте класс CopyOnWriteArrayList. Также имеет некоторые обратные спины, но в большинстве случаев это лучший вариант, а затем полная синхронизация.

При выборе между двумя вариантами следует учитывать следующие моменты: синхронизация является пуленепробиваемым решением, если это сделано правильно, это очень дорогостоящая работа, требующая много испытаний, которая не является тривиальной. Так что это уже большой откат. Плюс в большинстве случаев читает outnumber write или Array размер достаточно мал (скажем, до нескольких сотен элементов), где допустима копия на запись. Поэтому я полагаю, что большинство случаев CopyOnWriteArrayList было бы предпочтительнее. Дело в том, что при выборе между двумя вариантами выше нет четкого ответа. Программисту нужно посмотреть на обстоятельства и выбрать вариант, который лучше подходит для его/ее случая.

+0

«CopyOnWriteArrayList» не является «в конечном счете лучшим вариантом». Его название уже предполагает, что у него значительные затраты, что может быть значительно дороже, чем «полная синхронизация». Кроме того, даже использование 'synchronized' не является« пуленепробиваемым »; есть много, что вы можете сделать неправильно. – Holger

+0

@ Хольджер: да, есть много вещей, которые вы можете сделать неправильно (во что угодно, пока вы что-то делаете), но если вы правильно выполняете синхронизацию, это пуленепробиваемый. Что касается CopyOnWriteArrayList, то определенно лучший вариант, если число чтений значительно превышает число записей. Также, если ваш массив не слишком большой. Поэтому программисту нужно посмотреть на обстоятельства и выбрать вариант, который лучше подходит для его/ее дела –

+0

«так что программист должен смотреть на обстоятельства и выбирать ...» звучит намного лучше, чем смелый «в конечном счете лучший вариант». Вы не знаете, читает ли это намного больше числа записей в случае OP. – Holger