Java 设计问题:这是否只适用于生产者/消费者?

Java 设计问题:这是否只适用于生产者/消费者?,java,concurrency,producer-consumer,java.util.concurrent,futuretask,Java,Concurrency,Producer Consumer,Java.util.concurrent,Futuretask,我正试图提高索引lucene文件的性能。为此,我创建了一个工人“LuceneWorker”,负责这项工作 给定下面的代码,“并发”执行会变得非常慢。我想我知道为什么——因为未来发展到了极限,几乎没有记忆来执行LuceneWorker的另一项任务 问:有没有办法限制进入遗嘱执行人的“工人”数量?换句话说,如果存在“n”个未来,是否不继续并允许首先对文档进行索引 我的直觉方法是,我应该使用ArrayBlockingQueue构建消费者/生产者。但在重新设计之前,我想知道我是否正确 E

我正试图提高索引lucene文件的性能。为此,我创建了一个工人“LuceneWorker”,负责这项工作

给定下面的代码,“并发”执行会变得非常慢。我想我知道为什么——因为未来发展到了极限,几乎没有记忆来执行LuceneWorker的另一项任务

问:有没有办法限制进入遗嘱执行人的“工人”数量?换句话说,如果存在“n”个未来,是否不继续并允许首先对文档进行索引

我的直觉方法是,我应该使用ArrayBlockingQueue构建消费者/生产者。但在重新设计之前,我想知道我是否正确

        ExecutorService executor = Executors.newFixedThreadPool(cores);
        List<Future<List<Document>>> futures = new ArrayList<Future<List<Document>>>(3);
        for (File file : files)
        {
            if (isFileIndexingOK(file))
            {
                System.out.println(file.getName());
                Future<List<Document>> future = executor.submit(new LuceneWorker(file, indexSearcher));
                futures.add(future);
            }
            else
            {
                System.out.println("NOT A VALID FILE FOR INDEXING: "+file.getName());
                continue;   
            }
        } 

        int index=0;
        for (Future<List<Document>> future : futures)
        {
            try{

                List<Document> docs = future.get();

                for(Document doc : docs)
                    writer.addDocument(doc);    


            }catch(Exception exp)
            {
                //exp code comes here.
            }
        }
ExecutorService executor=Executors.newFixedThreadPool(核心);
列表期货=新的ArrayList(3);
用于(文件:文件)
{
如果(isFileIndexingOK(文件))
{
System.out.println(file.getName());
Future-Future=executor.submit(新LuceneWorker(文件,indexSearcher));
期货。添加(期货);
}
其他的
{
System.out.println(“不是用于索引的有效文件:+FILE.getName());
继续;
}
} 
int指数=0;
for(未来:未来)
{
试一试{
List docs=future.get();
用于(文档:文档)
writer.addDocument(doc);
}捕获(异常扩展)
{
//exp代码在这里。
}
}

如果要限制等待作业的数量,请将
ThreadPoolExecutor
与有界队列一起使用,如
ArrayBlockingQueue
。还要滚动您自己的
RejectedExecutionHandler
,以便提交线程等待队列中的容量。由于
newFixedThreadPool
使用无限
LinkedBlockingQueue
,因此不能使用
Executors
中的便利方法

根据LuceneWorker类的标准输入大小和复杂性,我可以想象使用Fork/Join框架至少部分地解决这个问题。使用JDK 8的实现(包含在中)时,I/O操作不会产生任何问题