Шаблон проектирования для Java: это кому-нибудь знакомо? - PullRequest
2 голосов
/ 11 марта 2009

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

Коллекция объектов, назовем их «источниками», создает данные, если вы вызываете для них метод. Экземпляр ScheduledThreadPoolExecutor (из <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html" rel="nofollow noreferrer">java.util.concurrent</a>) используется для периодического чтения данных в источниках и помещения данных в общую исходящую очередь:

--o
      method calls    +-----+
--o       <--         |  o  |     --->    |||||||||||
          -->         | o o |
--o      data         +-----+

sources             thread pool          outbound queue

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

Ниже приведен код для добавления нового источника. Мне интересно, что произойдет, если я удалю источник из коллекции.

public void vAddSource(ISource src)
{
    this._rgSources.add(src);
    final ISource srcT = src;
    // q is the outbound queue, which is a private member in the class
    // defining this method. Name is abbreviated for readability
    Runnable cmd = new Runnable() { public void run() { q.add(srcT.sRead()); } }
    // tpx is the thread pool
    this._tpx.scheduleAtFixedRate(cmd, 0L, 1000L, TimeUnit.MILLISECONDS);
}

Теперь, способ работы Java - если я понял это правильно - src и т. Д. - это идентификаторы объектов, которые передаются по значению, поэтому в приведенном выше коде есть только один объект ISource, и идентификатор для него добавляется в Коллекция, а также передается в пул потоков. Если я удаляю идентификатор из коллекции, объект все еще там, поэтому пул потоков будет продолжать читать из него, как будто ничего не произошло.

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

Ответы [ 3 ]

3 голосов
/ 11 марта 2009

ThreadPoolExecutor (и, следовательно, ScheduledThreadPoolExecutor) имеет метод remove(Runnable). Вы также можете быть заинтересованы в FutureTask, который можно отменить (хотя это не приведет к его удалению из рабочей очереди).

ETA (от Hanno Fietz, из ответа pgras): для этого также необходимо сопоставить Runnables с источником, чтобы метод removeSource мог вызвать ThreadPoolExecutor.remove с правильным значением.

2 голосов
/ 11 марта 2009

Одним из решений будет сохранение соответствия между источниками и Runnables, чтобы вы могли реализовать метод removeSource.

Другим способом было бы сохранить WeakReference для источника вместо жесткого и позволить Runnable завершить себя, если источник был собран мусором.

0 голосов
/ 22 октября 2012

Вы пишете, что не знаете о паттерне. java.lang.Runnable() использует шаблон команды - шаблон проектирования поведения.

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