重用Runnable的最佳方法

时间:2010-05-05 14:46:41

标签: java multithreading concurrency lucene

我有一个实现Runnable的类,目前正在使用Executor作为我的线程池来运行任务(将文档索引到Lucene中)。

executor.execute(new LuceneDocIndexer(doc, writer));

我的问题是我的Runnable类创建了许多Lucene Field对象,我宁愿重复使用它们,然后在每次调用时创建新对象。重用这些对象的最佳方法是什么(Field对象不是线程安全的,所以我不能简单地将它们设置为静态) - 我应该创建自己的ThreadFactory吗?我注意到一段时间后程序开始急剧下降,我唯一能想到的就是它的GC开销。我目前正试图描述该项目,以确保这甚至是一个问题 - 但现在让我们假设它是。

4 个答案:

答案 0 :(得分:14)

您的问题询问如何重复使用Runnable,因此我将忽略其他详细信息并简单回答该问题。

如果您使用的是ThreadPoolExecutor,则可以使用[ThreadPoolExecutor #afterExecute] [1]方法将Runnable对象返回到'cached'Runnables的池/队列。

[1]:http://java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#afterExecute(java.lang.Runnable,java.lang.Throwable)

答案 1 :(得分:5)

Runnable对象是可重用的。它不是线程对象。

最好的方式?这是你的方式: - )

我认为这比一个可运行的问题更像是一个简单的问题。

答案 2 :(得分:1)

您可能希望进行更多基准测试,以确定导致减速的原因。

我愿意打赌你的问题与Field实例的创建无关。 Field没有任何终结器,并且它们不是为了合并而设计的。

答案 3 :(得分:1)

现在我决定只使用一个简单的Producer-> Consumer模型。我将BlockingQueue传递给每个索引器,而不是将文档传递给索引,然后让程序的主驱动程序将新文档添加到该队列。索引器然后反馈[有界]队列并重用Field个对象并共享线程安全的IndexWriter

我找到了一个我可能没有打电话给HttpMethod.releaseConnection()的地方,这可能导致我的记忆问题(不确定)。