Java的设计模式:这对任何人来说都很熟悉吗?

时间:2009-03-11 10:53:27

标签: java design-patterns

在我的应用程序中,我有以下反复出现的模式,我觉得这是一些我不知道的常见模式的不完整或扭曲的版本。在我的实现中,我似乎无法找到实现特定操作的好方法,如下所述。

一组对象,我们称之为“源”,如果你在它们上调用一个方法,就会产生数据。 ScheduledThreadPoolExecutor的实例(来自java.util.concurrent)用于定期对源进行读数并将数据放在公共出站队列中:

--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 个答案:

答案 0 :(得分:3)

ThreadPoolExecutor(因此ScheduledThreadPoolExecutor)有remove(Runnable)方法。您可能也对可以取消的FutureTask感兴趣(尽管不会将其从工作队列中删除)。

ETA(由Hanno Fietz撰写,来自pgras的回答):这还需要将Runnables映射到源,以便removeSource方法可以使用正确的方法调用ThreadPoolExecutor.remove。

答案 1 :(得分:2)

一种解决方案是在源和Runnables之间保持映射,以便您可以实现removeSource方法。

另一种方法是将WeakReference保留在源而不是硬盘上,如果源是垃圾回收的话,让Runnable自行终止。

答案 2 :(得分:0)

你写的是你不知道这种模式。 java.lang.Runnable()使用命令模式 - 行为设计模式。