правильная синхронизация объекта карты, созданного в основном потоке и переданного в новые потоки - PullRequest
2 голосов
/ 24 января 2011

Я пытаюсь разработать программу, которая принимает запросы на данные, которые хранятся на карте.Карта объявлена ​​в основном методе, как показано ниже:

Map m = Collections.synchronizedMap(new HashMap());
synchronized(m) {
        while (listening) {

            new BrokerLookupServerHandlerThread(serverSocket.accept(), m).start();

        }
}

Код для BrokerLookupServerHandlerThread принимает входные данные и делает их одной из переменных объекта.Если я буду использовать его в этом классе, будет ли обновляться исходная карта?Я понимаю, что Java передается по значению (я привык к C / C ++), поэтому я просто хотел убедиться, имеет ли смысл реализация синхронизированного объекта.

    private Socket socket = null;
//private String t ="MSFT";
public Map m;

public BrokerLookupServerHandlerThread(Socket socket, Map m) {
    super("NamingServerHandlerThread");
    this.socket = socket;
    this.m = m;
    System.out.println("Created new Thread to handle client");
}

Спасибо за вашу помощь.

Ответы [ 2 ]

1 голос
/ 24 января 2011

Да, оригинальный объект будет обновлен.Я предлагаю вам использовать ConcurrentHashMap , хотя.

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

1 голос
/ 24 января 2011

Да, изменения, внесенные в карту, будут видны обоим потокам.

Java действительно использует передачу по значению - но значение в этом случае является ссылкой (аналогично указателю).Значение переменной ссылочного типа в Java - всегда ссылка на объект или ноль.Это никогда не сам объект.

Так что ваш код не создаст новую карту.Существует очень мало операций, которые неявно создают новый объект.Я могу думать только об использовании строковых литералов (где литералы интернированы в любом случае) и автобоксе примитивных типов.Кроме этого, вы получите новый объект только через оператор new.(Очевидно, что любой метод, который вы вызываете, мог бы создать новый объект тоже ...)

Обратите внимание, что это совершенно отдельно от вопроса синхронизации между потоками.Бизнес по копированию объектов против копирования ссылок ортогонален многопоточности.В этом случае похоже, что вы решили многопоточность, используя Collections.synchronizedMap;как говорит Пангея, вы можете вместо этого использовать ConcurrentHashMap, который не будет использовать почти столько же блокировок (если есть).Другая реализация интерфейса ConcurrentMap - это ConcurrentSkipListMap.Посмотрите документы для обоих классов, чтобы решить, что подходит вам лучше всего.

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