简体   繁体   English

重用Runnable的最佳方法

[英]Best way to reuse a Runnable

I have a class that implements Runnable and am currently using an Executor as my thread pool to run tasks (indexing documents into Lucene). 我有一个实现Runnable的类,我目前使用Executor作为我的线程池来运行任务(将文档索引到Lucene)。

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

My issue is that my Runnable class creates many Lucene Field objects and I would rather reuse them then create new ones every call. 我的问题是我的Runnable类创建了许多Lucene Field对象,我宁愿重复使用它们,然后在每次调用时创建新对象。 What's the best way to reuse these objects ( Field objects are not thread safe so I cannot simple make them static) - should I create my own ThreadFactory ? 重用这些对象的最佳方法是什么( Field对象不是线程安全的,所以我不能简单地将它们设置为静态) - 我应该创建自己的ThreadFactory吗? I notice that after a while the program starts to degrade drastically and the only thing I can think of is it's GC overhead. 我注意到一段时间后程序开始急剧下降,我唯一能想到的就是它的GC开销。 I am currently trying to profile the project to be sure this is even an issue - but for now lets just assume it is. 我目前正在尝试对项目进行分析,以确保这甚至是一个问题 - 但是现在让我们假设它是。

Your question asks how to reuse a Runnable, so I am going to ignore the other details adn simply answer that question. 您的问题询问如何重用Runnable,因此我将忽略其他详细信息并简单回答该问题。

If you are using a ThreadPoolExecutor, you can use the [ThreadPoolExecutor#afterExecute][1] method to return the Runnable object to a pool/queue of 'cached' Runnables. 如果您使用的是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]: http//java.sun.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.html#afterExecute (java.lang.Runnable,java.lang.Throwable)

A Runnable object is reusable. Runnable对象是可重用的。 It is thread object which is not. 它不是线程对象。

Best way ? 最好的办法 ? it is your way :-) 这是你的方式:-)

I think it is more a lucene question than a runnable question. 我认为这比一个可运行的问题更像是一个简单的问题。

You might want to do some more benchmarking to nail down what's causing your slowdowns. 您可能希望进行更多基准测试,以确定导致速度下降的原因。

I'm willing to bet that your problem is not related to the creation of Field instances. 我愿意打赌你的问题与Field实例的创建无关。 Field doesn't have any finalizers, and they're not designed to be pooled. Field没有任何终结器,并且它们不是为了汇集而设计的。

For now I have decided to just use a simple Producer->Consumer model. 现在我决定只使用一个简单的Producer-> Consumer模型。 I pass a BlockingQueue to each indexer, rather then a document to index, and then have the main driver of the program add new documents to that queue. 我将BlockingQueue传递给每个索引器,而不是将文档传递给索引,然后让程序的主驱动程序将新文档添加到该队列。 The Indexers then feed off that [bounded] queue and reuse the Field objects and share the thread-safe IndexWriter . 索引器然后反馈该[有界]队列并重用Field对象并共享线程安全的IndexWriter

I did find a place where I was possibly not calling HttpMethod.releaseConnection() so that could have caused my memory issues (uncertain). 我确实找到了一个我可能不会调用HttpMethod.releaseConnection()的地方,这可能导致我的内存问题(不确定)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM