Если вы работаете в HDFS через NFS, то вы можете ожидать, что большинство простых команд будут работать правильно (например, ls
, cd
, mkdir
, mv
, rm
, chmod
, [ 116], chown
). Единственная потребность в команде hadoop fs
или hdfs dfs
- если вы используете расширенные списки ACL или хотите выполнять другие специфичные для Hadoop вещи, например:
hadoop fs -setrep
hdfs dfs -expunge
Да, вы должны. По сути, я бы синхронизировал для любую операцию , если список можно было бы использовать для записи одновременно.
Обычно я нахожу коллекции попадающими в две категории - те, которые создаются, инициализируются и затем никогда больше не изменяются ( потокобезопасный), и те, которые изменяются с течением времени (не потокобезопасен, блокировка для любого доступа).
Если вы используете Reflector для проверки кода, вы получите что-то вроде этого:
public bool Contains(T item)
{
if (item == null)
{
for (int j = 0; j < this._size; j++)
{
if (this._items[j] == null)
{
return true;
}
}
return false;
}
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < this._size; i++)
{
if (comparer.Equals(this._items[i], item))
{
return true;
}
}
return false;
}
Как видите, это простая итерация по элементам, которая определенно является операцией чтения. Если вы используете его только для чтения (и ничего не изменяет элементы), то нет необходимости блокировать. Если вы начнете изменять список в отдельном потоке, вам, безусловно, потребуется синхронизировать доступ.
List
, скорее всего, операция чтения. Возможно, что какой-то другой поток пишет в коллекцию, когда вы ее читаете.
Если писатель может писать одновременно, List.Contains определенно не является потокобезопасным. Вам нужно будет обернуть его и любые другие операции чтения и записи с блокировкой.
Да, ты должен волноваться! List.Contains просто получает EqualityComparer, а затем перебирает все элементы, содержащиеся в списке, сравнивая элемент, переданный в качестве параметра, с элементом по индексу текущей итерации, поэтому, если список изменяется во время итерации, результаты могут быть непредсказуемыми.
В многопоточной среде вам необходимо убедиться, что запись в коллекцию не ведется одновременно. Вот код от рефлектора, сама коллекция не предоставила вам никакой блокировки, так что вы выиграли.
public bool Contains(T item)
{
if (item == null)
{
for (int j = 0; j < this._size; j++)
{
if (this._items[j] == null)
{
return true;
}
}
return false;
}
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
for (int i = 0; i < this._size; i++)
{
if (comparer.Equals(this._items[i], item))
{
return true;
}
}
return false;
}
Можно с уверенностью предположить, что это НЕ потокобезопасная операция. MSDN-описание подводит итог:
... этот метод использует коллекцию методы Equals и CompareTo для объектов на предмет, чтобы определить, является ли предмет существует.
Итак, после операции чтения идет операция сравнения.
Согласно документу ...
Перечисление через коллекцию по своей сути не является Потокобезопасная процедура.
Итак, я бы сказал, нет, это не потокобезопасный. Вы должны заблокировать его.
Считается операцией чтения. Вы не столкнетесь с какими-либо условиями гонки, но если вы беспокоитесь о получении последней версии, вы можете сделать список List
изменчивым
.
Согласно документации MSDN :
Открытые статические (Shared в Visual Basic) члены этого типа потокобезопасны. Ни один из членов экземпляра не гарантированно является потокобезопасным.
Класс ReaderWriterLock , похоже, создан для синхронизации, которую вы ищете.