Java Collections.synchronizedMap () с определением сложного типа - PullRequest
2 голосов
/ 17 августа 2011

Предположим, у меня есть класс такого рода:

public class MyMap<K, V> implements Map<Set<K>, V> {
  ...
}

, и я хотел бы иметь возможность принудительно синхронизировать его.Одним из способов является внутренняя синхронизация методов (возможно, с синхронизированными ключевыми словами), но если я намерен использовать его для более общего использования, то может быть лучше использовать внешнюю синхронизацию, возможно, с методом Collections.synchronizedMap ().

Проблема возникает в классе, где я пытаюсь реализовать это: предположим, у меня есть следующий класс:

public class Foo {
  MyMap<String, Object> _myMap;
  public Foo() {
    _myMap = Collections.synchronizedMap(new MyMap<String, Object>());
  }
}

В строке 4 класса я получаю ошибку «Несоответствие типов: невозможно преобразовать из карты»<Установите для <String>, Object> значение MyMap ".Eclipse предлагает мне сделать одно из двух: либо добавить приведение к MyMap , либо изменить тип _myMap на Map , Object>.Однако я, очевидно, не хочу делать последнее, поскольку весь смысл использования MyMap, а не Map, состоит в том, чтобы я мог воспользоваться дополнительными функциями, которые я реализовал в MyMap.Затем, когда я пытаюсь добавить приведение, как они предлагают, чтобы строка теперь выглядела как

_myMap = (MyMap<String, Object>) Collections.synchronizedMap(new MyMap<String, Object>);

, я получаю следующую ошибку, когда код фактически выполняется:

java.lang.ClassCastException: java.util.Collections$SynchronizedMap cannot be cast to ****.MyMap

ItПохоже, что synchronizedMap () понижает (?) MyMap до его «истинного» типа, который является Map , Object >>, и затем не позволяет мне преобразовать его обратно в MyMap, какой типЯ перешел в synchronizedMap ().

Есть ли способ обойти синхронизированную карту для работы с этим классом?Если нет, то какой может быть рекомендуемый метод достижения внешней или синхронизации?

Возможно, в качестве дополнительного вопроса, является ли этот метод реализации интерфейса, где параметры типа не являются простыми типами (например, нетривиальным множеством в первом параметре Map) обычно используется на практике?Может ли реализующий класс (в данном случае MyMap) когда-либо параметризироваться с чем-либо, кроме простых типов - другими словами, даже если кто-то реализует что-то вроде Map< Set< K>, V>, может ли реализующий класс когда-либо иметь что-то кроме в качестве его параметров (несмотря на дополнительные неиспользуемые параметры)?

На совершенно не связанной стороне замечание, кто-нибудь знает, как я могу обойти странный захват тега (так что мне не нужно ставить пробелы вроде "Карта "), даже когда я заключаю это в блоки?

Ответы [ 2 ]

2 голосов
/ 17 августа 2011

Если вы ознакомитесь с javadocs для Collections.synchronizedMap (см. здесь ), то вы увидите, как на самом деле вы должны использовать это и что оно делает. Главное, на что нужно обратить внимание, - это то, что карта, которую вы проходите, обернута в новую синхронизированную реализацию Map, и эта реализация отличается от MyMap, поэтому явное приведение не выполняется.

Что касается решения вашей проблемы, я не уверен на 100%, что вы ищете, но будет ли простой ConcurrentHashMap недостаточно? Посмотрите здесь для Javadocs.

1 голос
/ 17 августа 2011

Проблема в том, что вы определяете свое поле как "MyMap". Если вы намереваетесь использовать внешнюю синхронизацию, то вы должны использовать только карту, и вы даже не сможете преобразовывать ее в MyMap позже.

Причина в том, что SynchronizedMap на самом деле не "добавит" синхронизацию в ваш класс, но вернет синхронизированную реализацию новой Map, оборачивая экземпляр карты, который вы передаете, в качестве параметра.

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