Java 无法使用线程执行代码块中的所有语句
我试图读取文件夹中的许多文件,并使用线程同时处理它们 程序的结构如下所示:Java 无法使用线程执行代码块中的所有语句,java,multithreading,groovy,Java,Multithreading,Groovy,我试图读取文件夹中的许多文件,并使用线程同时处理它们 程序的结构如下所示: // Assuming there are 5 files in the directory // creating the threads ExecutorService pool = Executors.newFixedThreadPool(5) ExecutorCompletionService service = new ExecutorCompletionService(pool) directory.li
// 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()
}
}
这里的call方法创建另一个对象并对其调用一个方法
但奇怪的是,程序在执行call方法中的某些行后终止(它没有到达其中的final语句)。我在这里感到困惑。有人能解释一下正在发生的事情吗。请帮助我首先,您如何知道您的
调用
方法中只有几行被执行,而不是全部执行?我看到您发布的代码发生这种情况的唯一方式是,创建ConfigInfo
对象会引发异常
我尝试复制您正在描述的场景,但我仅在可调用
中将工作卸载到新的守护进程线程
时,才设法让程序退出。我的SSCCE见下文。取决于您是否离开thread.setDaemon(true)代码>调用在所有线程执行后,或在将任何输出写入控制台之前,程序很好地完成
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;
}
}
}
import java.util.concurrent.Callable;
导入java.util.concurrent.ExecutorService;
导入java.util.concurrent.Executors;
公共类执行器服务演示{
私有静态ExecutorService池=Executors.newFixedThreadPool(5);
私有静态void createAndExecuteThreads(){
对于(int i=0;i<5;i++){
提交(新的DummyCallable(“Callable”+i));
}
}
公共静态void main(字符串[]args){
createAndExecuteThreads();
pool.shutdown();
}
私有静态类DummyCallable实现了Callable{
私有最终字符串消息;
私有DummyCallable(字符串amessage){
消息=消息;
}
@凌驾
公共对象调用()引发异常{
Runnable Runnable=新的Runnable(){
@凌驾
公开募捐{
试一试{
睡眠(5000);
System.out.println(“message=“+message”);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
};
线程线程=新线程(可运行);
setDaemon(true);
thread.start();
返回null;
}
}
}
您是否可以在新的LogfileDataProcessor(configObject,param).processFileContent()方法中执行类似的操作?您需要程序等待线程完成。例如,您可以使用CountDounLatch:
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();
}
}
您可以将闩锁作为构造函数参数传递到线程中。要更快获得更好的帮助,请发布一个。我看到您进行了编辑。我们能期待很快看到SSCE吗?我已经编辑了call()方法。运行时程序会打印记录器注释,但它似乎不会创建LogfileDataProcessor对象并调用processFileContent方法。希望能给你一个更好的主意“希望能给你一个更好的主意”那么,这对我的问题是“不”吗?(耸耸肩)祝你好运。非常感谢你帮助我。倒计时闩锁成功了:-)现在程序运行良好。想想看,可能有更好的解决方案:您使用的是ExecutroService,所以提交后可以调用pool.shutdown();并等待线程完成:pool.waittermination(10,TimeUnit.MINUTES);我认为这是最简单的实现,没有额外的锁存器。这也是同样的道理。感谢您提供的信息。您也可以(在调用pool.shutdown()
)执行pool.waittermination(Long.MAX\u VALUE,TimeUnit.NANOSECONDS)
永久等待(请参阅)@tim\u yates:这是我之前的评论,事实上,场景是一样的。对于首先提出的问题,“processFileContent()”方法有一个HTTP post,该post不起作用。现在节目好了。感谢你的帮助。谢谢:)