Используйте Hashtable, Vector или HashMap или ArrayList в Java - PullRequest
12 голосов
/ 17 января 2009

Один мем, который подчеркивается при разработке Java, всегда использует ArrayList поверх Vector. Вектор устарел. Это может быть правдой, но у Vector и Hashtable есть преимущество в том, что они синхронизируются.

Я работаю с сильно параллельным ориентированным приложением, разве не было бы полезно использовать объекты, синхронизированные как Vector? Кажется, у них есть свое место?

Ответы [ 6 ]

17 голосов
/ 17 января 2009

ConcurrentHashMap на намного быстрее , чем Hashtable. Это одновременное , а не только синхронизированное. Он допускает несколько читателей / писателей одновременно.

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

17 голосов
/ 17 января 2009

Проблема с Vector и Hashtable заключается в том, что они синхронизируются только локально. Они не сломаются (как в поврежденных данных) в параллельном приложении, однако, из-за локальной синхронизации (например, get синхронизируется, но только до возврата get), вы все равно захотите выполнить собственную синхронизацию для таких ситуаций, как как итерация по содержанию. Теперь даже вашему положительному методу требуется дополнительная синхронизация для взаимодействия с итерационной синхронизацией, и вы попадаете в ситуацию, когда ваш Hashtable / Vector синхронизируется дважды.

13 голосов
/ 17 января 2009

Если вам нужен синхронизированный ArrayList или HashMap, вы можете обернуть их.

List list = Collections.synchronizedList(new ArrayList(...));
Map m = Collections.synchronizedMap(new HashMap(...));

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

8 голосов
/ 17 января 2009

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

Также обратите внимание, что Collections.synchronizedList() можно использовать для создания синхронизированного представления в любой реализации List, поэтому вам не нужно привязываться к характеристикам Vector (вы можете захотеть синхронизированный LinkedList например).

3 голосов
/ 17 января 2009

Вы можете использовать статические методы Коллекции для преобразования Списка или Карты в синхронизированную версию: http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collections.html#synchronizedList(java.util.List)

Как правило, вам обычно нужно заблокировать более одного вызова в списке или на карте.

0 голосов
/ 17 января 2009

Мне кажется, что вам нужна только одна коллекция, чтобы обеспечить безопасность потоков:

  • Если коллекция видна снаружи класса (публичная область или область по умолчанию)
  • Если вы возвращаете дескриптор в коллекцию из метода
  • Если коллекция является статическим членом вашего класса

Все это, вероятно, плохие идеи по дизайну.

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

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