Я держу карту объектов, и каждый раз, когда объект добавляется к ней, все остальные объекты на карте должны быть уведомлены о новом объекте и наоборот. Эти объекты запускаются сами по себе:
thread
процесс (каждый из них запущен с main
) может вызывать метод, который добавляет их на карту, чтобы объект мог быть добавлен во время итерации, вызванной добавлением предыдущего объекта.Как перебирать карту при одновременном добавлении к ней значений?
Это пример кода, который у меня есть. Вот объекты, о которых я говорил выше
class Notifier {
String name;
Hub hub;
Notifier(String name) {
this.name = name;
hub.add(this);
}
void acknowledge(String name) {
System.out.println(this.name + " was notified of " + name);
}
}
Вот это вещь, которая держит карту
public class Hub {
ConcurrentMap<String, Notifier> map = new ConcurrentHashMap<>();
void add(Notifier notifier) {
map.putIfAbsent(notifier.name, notifier);
Iterator<Entry<String, Notifier>> it = map.entrySet().iterator();
while (it.hasNext()) {
Entry<String, Notifier> entry = it.next();
if (!entry.getKey().equals(notifier.name)) {
entry.getValue().acknowledge(notifier.name);
notifier.acknowledge(entry.getKey());
}
}
}
}
Я попытался ConcurrentHashMap
, но это не должно быть так. Моя проблема в том, что результаты, которые я получаю, каждый объект уведомляется не один раз о другом , если я запускаю свои потоки вместе. Я получаю
notifier1 был уведомлен о notifier2
notifier1 был уведомлен о notifier2
notifier1 был уведомлен о notifier3
notifier1 был уведомлен о notifier3
notifier1 был уведомлен о notifier4
notifier1 был уведомлен о notifier4
и то же самое для других. Если я запускаю их 1 за другим, так что я пусть каждый конец добавив я получить правильный результат
notifier1 был уведомлен о notifier2
notifier1 был уведомлен о notifier3
notifier1 был уведомлен о notifier4
и аналогичные для других.
Я знаю, что эта карта, которую я выбрал, не дает никаких гарантий по обновлению итератора при добавлении (отправке) значений, поэтому я думаю, что именно поэтому это происходит. Во всяком случае, я знаю, что в этом эксперименте есть некоторые гонки.
Как сделать так, чтобы каждый объект был уведомлен ровно 1 раз из всех остальных? Может быть, эта параллельная карта не хороша, и мне нужно что-то синхронизировать? Меня не волнует порядок дополнений.
Что это за объекты? Есть ли веская причина сделать их независимыми потоками, а не использовать обратный подход? – chrylis
@chrylis это как клиенты и сервер. Каждый клиент, который приходит, уведомляется обо всех других клиентах, и они уведомляются об этом. не является ли это своего рода обратным вызовом уже потому, что хаб вызывает методы на объекте-уведомлении? извините, если я не понимаю. – Mark
Сортировка, но вы специально сказали, что они «работают на своих потоках», что не соответствует коду, который вы разместили здесь. – chrylis