Лучший способ управлять параллельным доступом к наборам Java

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

Важным отличием AJV от Joi является то, что AJV - это валидатор JSON Schema, а Joi - валидатор JavaScript. JSON Schema является кроссплатформенной, а Joi работает только на JavaScript. Таким образом, это не выбор между AJV и Joi, а выбор между JSON Schema и Joi.

У каждого подхода есть свои компромиссы, поэтому выбор, который вы выберете, во многом зависит от вашей конкретной ситуации.

AJV / JSON Schema

Большая победа, которую вы получаете от JSON Schema, заключается в том, что она кроссплатформенная. Реализации валидатора JSON Schema существуют на всех основных языках программирования. Независимо от того, какой язык вы выберете, вы можете использовать одну и ту же схему JSON на внешнем и внутреннем интерфейсах и получать согласованные результаты проверки. Напишите один раз, подтвердите в любом месте.

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

Вы можете выбрать AJV / JSON Schema, если вы используете в бэкэнде что-то отличное от JavaScript, или ваше приложение является публичным API, который может использоваться любым количеством приложений на любом количестве языков.

Joi

Самое большое преимущество Joi - это удобство использования. Он прост в использовании, легко расширяется и обладает всеми возможностями JavaScript.

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

Вы можете выбрать Joi, если вы используете JavaScript для внешнего интерфейса и внутреннего интерфейса и не ожидаете клиентов, не поддерживающих JavaScript, которые вам необходимо поддерживать. Это довольно узкая ситуация, но если это ваша ситуация, вы, скорее всего, получите больше или Джой, чем схема AJV / JSON.

Популярность

Звезды Github не являются большой мерой популярности. Если вы посмотрите ежедневные загрузки npm, вы увидите совсем другую историю (AVJ: 18,9 млн, Joi: 2,2 млн). Схема JSON гораздо шире используется, потому что она кроссплатформенная. AVJ - это всего лишь одна реализация на одном языке. Но если ваш стек разработки соответствует определенной нише Joi, он может быть таким же хорошим выбором или лучшим выбором, чем JSON Schema.

25
задан Community 23 May 2017 в 11:46
поделиться

7 ответов

Вектор и Список, возвращенный Collections.synchronizedList (), являются нравственно тем же самым. Я полагал бы, что Вектор эффективно (но не на самом деле) удержан от использования и всегда предпочитает синхронизируемый Список вместо этого. Одним исключением были бы старые API (особенно в JDK), которые требуют Вектора.

Используя явный ArrayList и синхронизирующийся независимо дает Вам возможность более точно настроить Вашу синхронизацию (или включением дополнительных действий во взаимоисключающем блоке или путем соединения множественных вызовов Списка в одном атомарном действии). Вниз сторона - то, что возможно написать код, который получает доступ к явному ArrayList вне синхронизации, которая повреждается.

Другой возможностью, которую Вы могли бы хотеть рассмотреть, является CopyOnWriteArrayList, который даст Вам потокобезопасность как в Векторе и синхронизировал ArrayList, но также и итераторы, которые не бросят ConcurrentModificationException, поскольку они отделываются неживого снимка данных.

Вы могли бы найти некоторые из этих недавних блогов по этим темам интересными:

23
ответ дан Alex Miller 28 November 2019 в 18:27
поделиться

Я настоятельно рекомендую книгу" Параллелизм Java на практике ".

Каждый выбор имеет преимущества/недостатки:

  1. Вектор - рассмотренный "устаревшим". Это может привлечь меньше внимания и исправлений ошибок, чем более основные наборы.
  2. Ваши собственные блоки синхронизации - Очень легкий стать неправильным. Часто дает более плохую производительность, чем выбор ниже.
  3. Collections.synchronizedList () - Выбор 2 сделанных экспертами. Это все еще не завершено из-за многоступенчатых операций, которые должны быть атомарными (доберитесь/измените/установите или повторение).
  4. Новые классы от java.util.concurrent - Часто имеют более эффективные алгоритмы, чем выбор 3. Подобные протесты о многоступенчатых операциях применяются, но инструменты для помощи Вам часто обеспечиваются.
13
ответ дан Darron 28 November 2019 в 18:27
поделиться

Я не могу думать о серьезном основании когда-либо предпочесть Vector более чем ArrayList. Операции списка на Vector синхронизируются, означая, что несколько потоков могут изменить его безопасно. И как Вы говорят, операции ArrayList могут синхронизироваться с помощью Collections.synchronizedList.

Помнят, что даже когда с помощью синхронизируемых списков, Вы все еще встретитесь ConcurrentModificationExceptions при итерации по набору, в то время как он изменяется другим потоком. Таким образом, важно скоординировать тот доступ внешне (Ваша вторая опция).

Одна общая техника, используемая для предотвращения итеративной проблемы, состоит в том, чтобы выполнить итерации по неизменным копиям набора. См. Collections.unmodifiableList

10
ответ дан jcrossley3 28 November 2019 в 18:27
поделиться

я всегда переходил бы к java.util.concurrent ( http://java.sun.com/javase/6/docs/api/java/util/concurrent/package-summary.html ) пакет сначала и видел бы, существует ли какой-либо подходящий набор. java.util.concurrent. Класс CopyOnWriteArrayList хорош при выполнении немногих изменений в списке, но большего количества повторений.

также я не верю Вектору, и Collections.synchronizedList предотвратит ConcurrentModificationException.

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

7
ответ дан richs 28 November 2019 в 18:27
поделиться

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

я полагаю, что, чтобы гарантировать, что итерация ориентирована на многопотоковое исполнение, необходимо будет обработать синхронизацию самостоятельно. При предположении, что тот же Вектор/Список/объект совместно используется несколькими потоками (и таким образом ведущей к проблемам), Вы не можете только синхронизироваться на том объекте самом?

3
ответ дан matt b 28 November 2019 в 18:27
поделиться

Самое безопасное решение состоит в том, чтобы избежать параллельного доступа к совместно используемым данным в целом. Вместо того, чтобы иметь потоки не-EDT воздействуют на те же данные, сделали, чтобы они звонили SwingUtilities.invokeLater() с Выполнимым, которое выполняет модификации.

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

2
ответ дан Michael Borgwardt 28 November 2019 в 18:27
поделиться

CopyOnWriteArrayList стоит для взгляда на. Это разработано для списка, который обычно читается из. Каждая запись заставила бы это создавать новый массив позади покрытий, таким образом, те, которые выполняют итерации через массив, не получат ConcurrentModificationException

2
ответ дан Javamann 28 November 2019 в 18:27
поделиться
Другие вопросы по тегам:

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