Написание синхронизированной оболочки безопасности потоков для NavigableMap

java.util.Collections в настоящее время предоставляет следующие служебные методы для создание synchronized оболочки для различных интерфейсов коллекций:

Аналогично, у него еще 6 unmodifiedXXX перегрузок.

Явным упущением здесь являются служебные методы для _10 _ . Это правда, что это extends SortedMap, но также SortedSet extends Set, Set extends Collection и Collections имеют специальные служебные методы для SortedSet и Set. Предположительно NavigableMap - полезная абстракция, иначе ее бы вообще не было, и все же для нее нет служебных методов.

Итак, вопросы:


person polygenelubricants    schedule 15.05.2010    source источник


Ответы (4)


Это была оплошность. Выполняется исправление.

Джош пишет:

«Они определенно принадлежат этому месту. Их отсутствие непреднамеренно.
Мы должны поместить их как можно скорее».

Я согласен, хотя никто из нас, инженеров, не хочет писать (и тестировать) все эти умопомрачительные методы пересылки. Дата публикации: 2006-08-21 00: 50: 41.0

Однако на это нужно время.

Обновление: что касается его реализации вручную, вы можете рассмотреть возможность взлома java.util пакета, так как вы хотите расширить static class SynchronizedSortedMap<K, V>, который объявлен как частный пакет. Иначе будет много копипаста кода. Вот начало:

package java.util;

import java.util.Collections.SynchronizedSortedMap;

public class NewCollections {

    public static <K, V> NavigableMap<K, V> synchronizedNavigableMap(NavigableMap<K, V> m) {
        return new SynchronizedNavigableMap<K, V>(m);
    }

    static class SynchronizedNavigableMap<K, V> extends SynchronizedSortedMap<K, V> implements NavigableMap<K, V> {
        private final NavigableMap<K, V> sm;

        SynchronizedNavigableMap(NavigableMap<K, V> m) {
            super(m);
            sm = m;
        }

        SynchronizedNavigableMap(NavigableMap<K, V> m, Object mutex) {
            super(m, mutex);
            sm = m;
        }

    }
}

Пусть IDE автоматически сгенерирует нереализованные методы NavigableMap и закодирует их так же, как это делает SynchronizedSortedMap. Вот ОДИН пример:

        @Override
        public K ceilingKey(K key) {
            synchronized (mutex) { return sm.ceilingKey(key); }
        }

Обратите внимание, что методы, которые возвращают, например, Set, вам также нужно обернуть его в SynchronizedSet. Опять же, за подробностями обращайтесь к источникам SynchronizedMap и SynchronizedSortedMap :)

Я не думаю, что это будет механический процесс, поскольку он включает в себя множество факторов.

person BalusC    schedule 16.05.2010
comment
Woot! Насколько авторитетен вопрос почему ?. Я не могу принять этот ответ прямо сейчас, поскольку в нем отсутствует как? Не могли бы вы это прокомментировать? Это все еще большая часть моего вопроса. Насколько сложно написать и протестировать эти умопомрачительные методы пересылки? Разве это не может быть полуавтоматически? И Т. Д. - person polygenelubricants; 16.05.2010
comment
Я бы просто скопировал static class SynchronizedMap и static class SynchronizedSortedMap из Collections источника, добавил свой собственный SynchronizedNavigableMap который extends SynchronizedSortedMap и украсил недостающие методы так же, как это делают два скопированных класса. Кода будет много, и уже поздно :) - person BalusC; 16.05.2010
comment
это такой механический и умопомрачительный процесс! Казалось бы, это должно быть автоматизировано! - person polygenelubricants; 16.05.2010

Верно ли, что в целом вы можете добавить такую ​​функцию синхронизированной потоковой безопасности?

Я считаю, что это правда. Определение безопасности потоков - это (IMO),

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

Теперь, приведенный ниже код гарантирует, что "Something" никогда не будет вызван несколькими потоками, верно? Поэтому я считаю, что нежелательное поведение не может возникнуть из-за того, что оно вызвано несколькими потоками; Он никогда не вызывается из нескольких потоков!

Вероятно, это также идея EJB. Компоненты EJB без сохранения состояния никогда не вызываются более чем одним потоком (это выполняется контейнером). Вот почему в спецификации EJB можно сказать: «Вам не нужно беспокоиться о безопасности потоков».

public class MakeSomethingThreadSafe implements Something {
    private final Object lock = new Object();
    private final Something subject;

    public MakeSomethingThreadSafe(Something subject){
        this.subject = subject;
    }

    public void someMethod(){
        synchronized(lock){
            subject.someMethod();
        }
    }
}

Или я что-то упускаю?

Чтобы сделать сообщение завершенным:

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

Я согласен со Стивеном.

Как бы вы написали свою собственную синхронизированную оболочку для NavigableMap?

Как мой пример кода ..

Верно ли, что в целом вы можете добавить такую ​​функцию синхронизированной потоковой безопасности? Если это такой механический процесс, можно ли его автоматизировать? (Плагин Eclipse и т. Д.)

Да, я думаю, это легко автоматизировать.

  1. Реализуйте интерфейс
  2. Сделайте 2 поля; Один для мьютекса, один для объекта.
  3. Создайте конструктор для внедрения темы.
  4. Сделайте каждый метод синхронизированным и делегируйте объекту.

Необходимо ли это повторение кода или его можно было бы избежать с помощью другого шаблона проектирования ООП?

Как для Set, Map и т. Д.? Мне кажется, что решить ее "нормальным" способом не представляется возможным ..

person Enno Shioji    schedule 15.05.2010

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

Я не могу придумать конкретную причину. Это либо

  • оплошность,
  • случай "вряд ли кто-нибудь воспользуется им", или
  • возможно, есть какие-то неочевидные технические трудности.

Но в любом случае причина не имеет значения. Утилиты нет, так что либо вы найдете стороннюю библиотеку, либо реализуете ее самостоятельно.

Верно ли, что в целом вы можете добавить такую ​​функцию синхронизированной потоковой безопасности?

В общем нет. Вам нужно понимать семантику класса, который вы привязываете, чтобы сделать потокобезопасным, чтобы выяснить, достаточно ли оболочки.

Если это такой механический процесс, можно ли его автоматизировать? (Плагин Eclipse и т. Д.)

Нет ... см. Выше.

Необходимо ли это повторение кода или его можно было бы избежать с помощью другого шаблона проектирования ООП?

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

person Stephen C    schedule 15.05.2010
comment
просто чтобы прояснить мое собственное понимание, является ли это шаблоном декоратора, который Collections делает в отношении классов-оболочек? например synchronizedSet возвращает Set, который украшает другой Set функцией защиты от угроз, но сам по себе не выполняет какой-либо Set-подобной работы? - person polygenelubricants; 15.05.2010

К вашему сведению, в Java 8 теперь это есть:

private NavigableMap<Date,T> map = Collections.synchronizedNavigableMap(...);

Пожалуйста, см. Документ Java8 на навигационной карте

person BlackLabrador    schedule 10.07.2014