Нужно ли синхронизировать вызов функции с защитой потоков? - PullRequest
3 голосов
/ 19 ноября 2008

Если я использую ConcurrentHashMap (где пут является потокобезопасным), и я предоставляю публичную функцию myPut, которая использует пут ConcurrentHashMap - нужно ли синхронизировать мою функцию?

значение: это должно быть синхронизировано?

ConcurrentHashMap map;  
public void myPut(int something) {  
   this.map.put(something);  
}

Ответы [ 5 ]

4 голосов
/ 19 ноября 2008

Поскольку ссылка map не объявлена ​​final, она может быть изменена. Следовательно, здесь есть потенциальная ошибка в потоке.

Если map должен быть изменяемой ссылкой, вам потребуется проделать дополнительную работу В противном случае используйте final. Действительно, используйте final всякий раз, когда можете, даже если это «проще» не делать. «final - это новый [старый] private.» Вы, вероятно, хотите сделать map private и универсальный тоже.

2 голосов
/ 24 декабря 2008

Утилиты параллелизма, такие как ConcurrentHashMap, спроектированы так, что вам не нужно синхронизировать: они будут обрабатывать потокобезопасный доступ внутри.

То, что Том говорит, правда, что вам нужно подумать о возможности изменения ссылки на карту. Если ссылка на самом деле не изменилась, то на практике вам это сойдет с рук: внутренняя синхронизация ConcurrentHashMap - и вообще-то java.util.concurrentlibrary - гарантирует, что объекты помещают на карту благополучно публикуются другие темы. Но я бы согласился, что даже в этом случае рекомендуется решить, может ли ссылка измениться, или нет, а затем явно указать это в коде («final», если это невозможно; что-то вроде «volatile» или AtomicReference, если может).

1 голос
/ 19 ноября 2008

Если вы используете ConcurrentHashMap, вы не должны синхронизировать «put», но это не значит, что ваши «put» будут вызываться по одному. Это зависит от уровня одновременности вашей карты ...

Итак, вы должны знать, что вы хотите.

Кстати, взгляните на Javadoc ConcurrentHashTable, все хорошо объяснено ...

-Patrick

0 голосов
/ 19 ноября 2008

Это зависит.

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

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

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

0 голосов
/ 19 ноября 2008

номер
Вы можете вызывать myPut несколько раз одновременно.
Путь будет вызываться по одному, потому что доступ к HashTable должен быть по одному. (см. также одновременную запись в общую память)

...