Сделать ваши коллекции потокобезопасными? - PullRequest
9 голосов
/ 02 октября 2008

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

Ответы [ 17 ]

13 голосов
/ 02 октября 2008

есть ли причина не использовать частную блокировку для обеспечения безопасности потока?

Это зависит. Ваша цель написать класс коллекции, к которому обращаются несколько потоков? Если так, сделайте это безопасным. Если нет, не тратьте свое время. К таким вещам относятся люди, когда говорят о «преждевременной оптимизации»

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

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

10 голосов
/ 02 октября 2008

Для Java вы должны оставить несинхронизированный для скорости. Потребитель коллекции может при желании обернуть в синхронизирующую оболочку .

6 голосов
/ 26 сентября 2010

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

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

...

Но если создание потока данных безопасно список так прост, почему Microsoft не добавить эти стандартные коллекции в рамки?

Ответ: ThreadSafeList является практически непригодный класс, потому что дизайн ведет вас по пути к плохому Код.

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

static int GetFirstOrDefault(ThreadSafeList<int> list) {
    if (list.Count > 0) {
        return list[0];
    }
    return 0; }

Этот код является классическим условием гонки. Рассмотрим случай, когда в списке есть только один элемент. Если другой поток удаляет этот элемент между оператором if и оператором return, оператор return выдаст исключение, поскольку он пытается получить доступ к неверному индексу в списке. Даже несмотря на то, что ThreadSafeList безопасен для потоков данных, ничто не гарантирует достоверность возвращаемого значения одного вызова при следующем вызове того же объекта

http://blogs.msdn.com/b/jaredpar/archive/2009/02/11/why-are-thread-safe-collections-so-hard.aspx

http://blogs.msdn.com/b/jaredpar/archive/2009/02/16/a-more-usable-thread-safe-collection.aspx

3 голосов
/ 02 октября 2008

Классы сбора должны быть максимально быстрыми. Поэтому оставьте замки вне.

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

2 голосов
/ 02 октября 2008

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

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

2 голосов
/ 02 октября 2008

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

2 голосов
/ 02 октября 2008

Я бы лично оставил это на усмотрение потребителей. Это сделает ваш класс коллекции более общим.

1 голос
/ 03 октября 2008

Действительно хорошая причина НЕ делать вашу коллекцию поточно-ориентированной - это улучшенная производительность однопоточности. Пример: ArrayList поверх Vector. Задержка безопасности потока для вызывающей стороны позволяет оптимизировать несинхронизированный вариант использования, избегая блокировки.

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

1 голос
/ 03 октября 2008

По сути, спроектируйте свою коллекцию как поточно-ориентированную, с блокировкой, реализованной двумя методами вашего класса: lock () и unlock (). Позвоните им куда угодно, но оставьте их пустыми. Затем создайте подкласс для вашей коллекции, реализуя методы lock () и unlock (). Два класса по цене одного.

1 голос
/ 02 октября 2008

Обеспечение безопасности потока коллекции - вот что убило классы Java Vector и Hashtable. Клиенту гораздо проще обернуть его в потоковую оболочку, как было предложено ранее, или синхронизировать доступ к данным в подмножестве методов, чем получать синхронизацию при каждом обращении к классу. Вряд ли кто-то использует Vector или Hashtable, и если они это сделают, над ними будут смеяться, потому что их замены (ArrayList и HashMap) - это миры быстрее. Что вызывает сожаление, поскольку я (исходя из фона C ++) очень предпочитаю имя «Вектор» (STL), но ArrayList здесь, чтобы остаться.

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