public class SimpleCub
{
public int X
{
get;
private set;
}
public int Y
{
get;
private set;
}
public int Z
{
get;
private set;
}
public SimpleCub(int x, int y, int z)
{
X = x;
Y = y;
Z = z;
}
#region Equals_GetHashCode Members
public override bool Equals(Object obj)
{
if (obj == null || GetType() != obj.GetType())
return false;
SimpleCub simpleCube = (SimpleCub)obj;
return ((simpleCube.X == X) && (simpleCube.Y == Y) && (simpleCube.Z == Z));
}
public override int GetHashCode()
{
Func<byte[], int> calcHash = (arr) =>
{
using (RIPEMD160Managed myRIPEMD160 = new RIPEMD160Managed())
{
return BitConverter.ToInt32(myRIPEMD160.ComputeHash(arr), 0);
}
};
List<byte> listBytes = new List<byte>(BitConverter.GetBytes(X));
listBytes.AddRange(BitConverter.GetBytes(Y));
listBytes.AddRange(BitConverter.GetBytes(Z));
return calcHash(listBytes.ToArray());
}
#endregion
}
по определенным правилам создаются допустим 10 экземпляров данного типа и добавляются в List<SimpleCub> list1 эти же созданные экземпляры добавляются в List<SimpleCub> list2
создается дочерний поток thread1 и передается в него list1
создается дочерний поток thread2 и передается в него list2
в дочерних потоках создается (в 1-м):
dic1 = new Dictionary<SimpleCub, object>();
(во 2-м):
dic2 = new Dictionary<SimpleCub, object>();
и соответсвенно добавляются элементы SimpleCub (в качестве ключа) в dic1 из list1
добавляются элементы SimpleCub (в качестве ключа) в dic2 из list2
далее в каждом из дочерних потоках создаются новые SimpleCub и добавляются в dic1 или dic2 в качестве ключа.
Вопрос:
Нужна ли блокировка(синхронизация) при добавлении элементов в dic1 и dic2 ?
Re: Синхронизация на доступ при добавлении объекта
А>Добрый день, А>На собеседовании задали вопрос:
А>есть класс:
А>
А> public class SimpleCub
А> {
А> public int X
А> {
А> get;
А> private set;
А> }
А> public int Y
А> {
А> get;
А> private set;
А> }
А> public int Z
А> {
А> get;
А> private set;
А> }
А> public SimpleCub(int x, int y, int z)
А> {
А> X = x;
А> Y = y;
А> Z = z;
А> }
А> #region Equals_GetHashCode Members
А> public override bool Equals(Object obj)
А> {
А> if (obj == null || GetType() != obj.GetType())
А> return false;
А> SimpleCub simpleCube = (SimpleCub)obj;
А> return ((simpleCube.X == X) && (simpleCube.Y == Y) && (simpleCube.Z == Z));
А> }
А> public override int GetHashCode()
А> {
А> Func<byte[], int> calcHash = (arr) =>
А> {
А> using (RIPEMD160Managed myRIPEMD160 = new RIPEMD160Managed())
А> {
А> return BitConverter.ToInt32(myRIPEMD160.ComputeHash(arr), 0);
А> }
А> };
А> List<byte> listBytes = new List<byte>(BitConverter.GetBytes(X));
А> listBytes.AddRange(BitConverter.GetBytes(Y));
А> listBytes.AddRange(BitConverter.GetBytes(Z));
А> return calcHash(listBytes.ToArray());
А> }
А> #endregion
А> }
А>
А>по определенным правилам создаются допустим 10 экземпляров данного типа и добавляются в List<SimpleCub> list1 А>эти же созданные экземпляры добавляются в List<SimpleCub> list2 А>создается дочерний поток thread1 и передается в него list1 А>создается дочерний поток thread2 и передается в него list2
А>в дочерних потоках создается (в 1-м): А>dic1 = new Dictionary<SimpleCub, object>();
А>(во 2-м): А>dic2 = new Dictionary<SimpleCub, object>();
А>и соответсвенно добавляются элементы SimpleCub (в качестве ключа) в dic1 из list1 А>добавляются элементы SimpleCub (в качестве ключа) в dic2 из list2
А>далее в каждом из дочерних потоках создаются новые SimpleCub и добавляются в dic1 или dic2 в качестве ключа.
А>Вопрос: А>Нужна ли блокировка(синхронизация) при добавлении элементов в dic1 и dic2 ?
Только если Вы пытаетесь работать с любым из словарей из более чем одного потока
Re: Синхронизация на доступ при добавлении объекта
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, samius, Вы писали:
S>>Я фигею с такого GetHashCode()!!! S>>Получить 160-битный хэшкод по 96и битам и обрезать его в 32
А>за отсутствием другого варианта используем RIPEMD160Managed
Сомневаюсь что нет другого варианта
А>вариант X ^ Y ^ Z не подходит....
Надо просто посмотреть чем не подходит. Если тем что дает один код для координат (1, 0, 0) и (0, 1, 0), то это решается по-другому. Например, сдвигом.
Re[3]: Синхронизация на доступ при добавлении объекта
Здравствуйте, Аноним, Вы писали:
А>в dic1 добавляются элементы только в потоке1, а в dic2 добавляются элементы только в потоке2
А>таким образом Ваш ответ блокировка(синхронизация) не нужна когда требуется добавлять новые SimpleCub в словари А>??
Ну а что именно Вы собираетесь лочить? У Вас, как я понял, есть готовый класс и не менее готовый словарь. Покажите псевдокодом, в каком именно месте Вы собираетесь ставить влокировку и поясните, от каких ситуаций она, по Вашему мнению, должна Вас эащитить.
"Нормальные герои всегда идут в обход!"
Re[4]: Синхронизация на доступ при добавлении объекта
От:
Аноним
Дата:
11.03.10 12:19
Оценка:
Здравствуйте, samius, Вы писали:
А>>за отсутствием другого варианта используем RIPEMD160Managed S>Сомневаюсь что нет другого варианта
А>>вариант X ^ Y ^ Z не подходит.... S>Надо просто посмотреть чем не подходит. Если тем что дает один код для координат (1, 0, 0) и (0, 1, 0), то это решается по-другому. Например, сдвигом.
Да, потому что одинаковый хэш для (1, 0, 0) и (0, 1, 0).
RIPEMD160Managed дает приемлемую производительность при подсчете хэша на 12 байт.
Хотя попробую покопать в строну сдвига...
Re[4]: Синхронизация на доступ при добавлении объекта
От:
Аноним
Дата:
11.03.10 12:34
Оценка:
Здравствуйте, samius, Вы писали:
А>>вариант X ^ Y ^ Z не подходит.... S>Надо просто посмотреть чем не подходит. Если тем что дает один код для координат (1, 0, 0) и (0, 1, 0), то это решается по-другому. Например, сдвигом.
придумал вот такой сдвиг:
int t = X << 8;
t ^= Y;
t <<= 8;
t ^= Z;
t <<= 8;
в t после сдвига в последней строчке содержится хэш.
Re[5]: Синхронизация на доступ при добавлении объекта
Здравствуйте, Аноним, Вы писали:
А>придумал вот такой сдвиг: А>
А> int t = X << 8;
А> t ^= Y;
А> t <<= 8;
А> t ^= Z;
А> t <<= 8;
А>
А>в t после сдвига в последней строчке содержится хэш.
Отлично. Только лучше int заменить на long и потом взять t.GetHashCode(). Тогда старшие байты координат не потеряются.
Re[4]: Синхронизация на доступ при добавлении объекта
От:
Аноним
Дата:
11.03.10 13:14
Оценка:
Здравствуйте, Jolly Roger, Вы писали:
JR>Ну а что именно Вы собираетесь лочить? У Вас, как я понял, есть готовый класс и не менее готовый словарь. Покажите псевдокодом, в каком именно месте Вы собираетесь ставить влокировку и поясните, от каких ситуаций она, по Вашему мнению, должна Вас эащитить.
Хоть "старые" экземпляры SimpleCub разделяются между 2-мя дочерними потоками (находясь в dic1 и dic2), они immutable экземпляры. При добавлении новых SimpleCub созданных в дочерних потоках вызывается только GetHashCode этих новых экземпляров. Т.е никаких накладных расходов/коллизий здесь не может быть со "старыми" экземплярами SimpleCub в дочерних потоках полученных от родительского потока.
Re[6]: Синхронизация на доступ при добавлении объекта
От:
Аноним
Дата:
11.03.10 13:24
Оценка:
Здравствуйте, samius, Вы писали:
S>Отлично. Только лучше int заменить на long и потом взять t.GetHashCode(). Тогда старшие байты координат не потеряются.
Спасибо Вам за помощь.
Re: Синхронизация на доступ при добавлении объекта
Единственное, что тут можно предположить это работа с листами. Если на момент добавления объектов из листов в диктионари, в радительском потоке возможна работа с этими листами, то тогда надо лочить листы.
Или я, что не так понял?
Re[2]: Синхронизация на доступ при добавлении объекта
От:
Аноним
Дата:
11.03.10 13:48
Оценка:
Здравствуйте, hooky-mars, Вы писали:
HM>Единственное, что тут можно предположить это работа с листами. Если на момент добавления объектов из листов в диктионари, в радительском потоке возможна работа с этими листами, то тогда надо лочить листы. HM>Или я, что не так понял?
Здесь проблем нет. После того как list1 и list2 переданы в дочерние потоки, в родительском потоке с ними нет никаких операций.
Re[5]: Синхронизация на доступ при добавлении объекта
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Jolly Roger, Вы писали:
JR>>Ну а что именно Вы собираетесь лочить? У Вас, как я понял, есть готовый класс и не менее готовый словарь. Покажите псевдокодом, в каком именно месте Вы собираетесь ставить влокировку и поясните, от каких ситуаций она, по Вашему мнению, должна Вас эащитить.
А>Хоть "старые" экземпляры SimpleCub разделяются между 2-мя дочерними потоками (находясь в dic1 и dic2), они immutable экземпляры. При добавлении новых SimpleCub созданных в дочерних потоках вызывается только GetHashCode этих новых экземпляров. Т.е никаких накладных расходов/коллизий здесь не может быть со "старыми" экземплярами SimpleCub в дочерних потоках полученных от родительского потока.
Мне это понятно Это-же Вы вроде как высказывали сомнения здесь
Re[6]: Синхронизация на доступ при добавлении объекта
От:
Аноним
Дата:
11.03.10 14:19
Оценка:
Здравствуйте, Jolly Roger, Вы писали:
А>>Хоть "старые" экземпляры SimpleCub разделяются между 2-мя дочерними потоками (находясь в dic1 и dic2), они immutable экземпляры. При добавлении новых SimpleCub созданных в дочерних потоках вызывается только GetHashCode этих новых экземпляров. Т.е никаких накладных расходов/коллизий здесь не может быть со "старыми" экземплярами SimpleCub в дочерних потоках полученных от родительского потока.
JR>Мне это понятно Это-же Вы вроде как высказывали сомнения здесь