我正在尝试读取文件夹中的多个文件并使用线程同时处理它们。
程序的结构如下:
// Assuming there are 5 files in the directory
// creating the threads
ExecutorService pool = Executors.newFixedThreadPool(5)
ExecutorCompletionService service = new ExecutorCompletionService(pool)
directory.listFiles().each { eachFile ->
service.submit(new FileReader(eachFile, param2))
}
// the FileReader class
class FileReader implements Callable {
File file
String param
FileReader(File file, String param){
this.file = file
this.param = param
}
Object call(){
LOG.info("Processing file" + filePath)
ConfigInfo configInfo = new ConfigInfo()
configInfo.setFilePath(filePath);
configInfo.setReaderUid(readerUid);
configInfo.setPatternsMap(patternsMap);
new LogfileDataProcessor(configObject, param).processFileContent()
}
}
此处的调用方法创建另一个对象并在其上调用方法。
但奇怪的是,程序在调用方法中执行了一些行后终止(它没有到达其中的最后一个语句)。我在这里很困惑。有人可以对正在发生的事情有所了解。请帮帮我
答案 0 :(得分:1)
您需要程序等待线程完成。例如,您可以使用CountDownLatch:
CountDownLatch latch = new CountDownLatch(numberOfFilesInDirectory);
directory.listFiles().each { eachFile ->
service.submit(new FileReader(eachFile, param2))
}
latch.await();
// And in your Callable:
class FileReader implements Callable {
File file
String param
FileReader(File file, String param){
this.file = file
this.param = param
}
public Object call() {
try {
LOG.info("Processing file" + filePath)
ConfigInfo configInfo = new ConfigInfo()
configInfo.setFilePath(filePath);
configInfo.setReaderUid(readerUid);
configInfo.setPatternsMap(patternsMap);
new LogfileDataProcessor(configObject, param).processFileContent();
} finally {
latch .countDown();
}
}
您可以将latch作为构造函数参数传递给线程。
答案 1 :(得分:0)
首先,您如何知道call
方法中只有几行被执行但不是全部?我发现使用您发布的代码发生的唯一方法是创建该ConfigInfo
对象会引发异常。
我尝试重现你正在描述的场景,但我只是设法让我的程序退出,如果在Callable
我将工作卸载到一个新的守护进程Thread
。请参阅下面的SSCCE。根据您是否将thread.setDaemon( true );
调用留在其中,程序在执行所有Thread
之后很好地完成,或者在将任何输出写入控制台之前完成。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ExecutorServiceDemo {
private static ExecutorService pool = Executors.newFixedThreadPool( 5 );
private static void createAndExecuteThreads(){
for( int i =0; i< 5; i++ ){
pool.submit( new DummyCallable( "Callable " + i ) );
}
}
public static void main( String[] args ) {
createAndExecuteThreads();
pool.shutdown();
}
private static class DummyCallable implements Callable<Object>{
private final String message;
private DummyCallable( String amessage ) {
message = amessage;
}
@Override
public Object call() throws Exception {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
Thread.sleep( 5000 );
System.out.println( "message = " + message );
} catch ( InterruptedException e ) {
e.printStackTrace();
}
}
};
Thread thread = new Thread( runnable );
thread.setDaemon( true );
thread.start();
return null;
}
}
}
您是否可以在new LogfileDataProcessor(configObject, param).processFileContent()
方法中执行类似操作?