При использовании шаблона одноэлементного проектирования другие методы должны использовать синхронизированное ключевое слово для обеспечения безопасности потока? - PullRequest
3 голосов
/ 04 апреля 2019

Я хочу убедиться, что следующий класс является поточно-ориентированным, следует ли использовать ключевое слово synchronized для других методов? Или используйте потокобезопасную структуру данных для хранения электронной почты. Что мне делать?

public class RecycleStation {
    private static volatile RecycleStation uniqueInstance;
    private static List<Email> recycleEmailList ;

    private RecycleStation() {
        recycleEmailList = new ArrayList<>();
    }

    public static RecycleStation getInstance() {
        if (uniqueInstance == null) {
            synchronized (RecycleStation.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new RecycleStation();
                }
            }
        }
        return uniqueInstance;
    }

    public void RecycleEmail(Email email) {
        recycleEmailList.add(email);
    }

    public void deleteEmail(Email email) {
        recycleEmailList.remove(email);
    }

    public void clear() {
        recycleEmailList.clear();
    }

}

Ответы [ 2 ]

2 голосов
/ 04 апреля 2019

Лучше использовать структуру данных thread-safe, atomic для ваших электронных писем, чем устанавливать synchronized в каждом из методов обновления.Синхронизация использует механизм ОС lock, который является дорогостоящей операцией, и ее следует избегать.

Я бы использовал ConcurrentLinkedQueue (пример ниже).

Относительно самого класса - Lazy-Initialization шаблон проектирования для поточно-ориентированного синглтона также может быть хорошим решением.

В вашем случае он имеет в основном "за":

  • Вы избегаетеиспользование synchronized в getInstance()
  • Немного улучшает время запуска
  • Потокобезопасен:)

Редактировать: Взгляните на эту статью , чтобы лучше понять, почему эта реализация является поточно-ориентированной.@Rafael сделал хорошее замечание: ленивая инициализация сама по себе не обязательно означает безопасность потоков.

После того, как все сказано и сделано, вот реализация:

public class RecycleStation  {
    private static RecycleStation uniqueInstance; //You don't need `volatile` here
    private static ConcurrentLinkedQueue<Email> recycleEmailList;

    // Here it all begins:
    private static class SingletonHolder {
        private static RecycleStation  instance = new RecycleStation();
    }
    public static RecycleStation getInstance() {
        return SingletonHolder.instance;
    }
    private RecycleStation () {
        recycleEmailList = new ConcurrentLinkedQueue<>();
    }

    // class functions:
    public void RecycleEmail(Email email) {
        recycleEmailList.add(email);
    }

    public void deleteEmail(Email email) {
        recycleEmailList.remove(email);
    }

    public void clear() {
        recycleEmailList = new ConcurrentLinkedQueue<>();
    }
}
1 голос
/ 04 апреля 2019

Во-первых, шаблон Singleton лучше всего реализовать как Enum в Java Во-вторых, каждая email функция манипуляции (clear, Recycle, delete) должна быть синхронизирована для обеспечения безопасности потока (ссылка относится к Enum, но то же самое относится ко всем без исключения Реализация Sinlgeton):

public synchronized void RecycleEmail(Email email)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...