Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 无法使用线程执行代码块中的所有语句_Java_Multithreading_Groovy - Fatal编程技术网

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不起作用。现在节目好了。感谢你的帮助。谢谢:)