繁体   English   中英

java 多线程执行器从不关闭线程

[英]java multi threading executor never shutdown threads

有人可以看看下面的程序吗?

它适用于小进程,但在完成大进程后不退出程序。

注意:如果是小型查询,大约50条记录(检索和更新),程序正在正常退出......

该程序的目的是从数据库中获取数据,go 到云端读取 JSON,验证数据并使用结果更新数据库中的记录。

public class ThreadLauncher
{

  public static void main(String args[])
   {
    final ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); // or hardcode a number



    List<Future<Runnable>> futures = new ArrayList<Future<Runnable>>();

    for (int n = 0; n < 10; n++)
    {
        Future f = service.submit(new Task(n));
        futures.add(f);
    }

    // wait for all tasks to complete before continuing
    for (Future<Runnable> f : futures)
    {
        try {

            f.get();
            //shut down the executor service so that this thread can exit

        } catch (InterruptedException e) {
            System.out.println("Exiting with InterruptedException : " + e.getMessage());
            e.printStackTrace();
        } catch (ExecutionException e) {
            System.out.println("Exiting with ExecutionException : " + e.getMessage());
            e.printStackTrace();
        }
    }
    service.shutdownNow();


    System.out.println("Exiting normally...");

}
}

 final class Task
    implements Runnable
{
private int loopCounter;
private int totalLoops = 5;


public Task(int counter)
{
    this.loopCounter = counter;
}

@Override
public void run()
 {
    try { 
        GCPJSON.getInstance().getGCPDataFromJSON(PRODDataAccess.getInstance().getDataToProcess(loopCounter,totalLoops));

        System.out.println("Task ID : " + this.loopCounter + " performed by " + 
     Thread.currentThread().getName());
    } catch (Exception e) {

        e.printStackTrace();
    }

 }
}

这是因为当您在executorService上调用shutdownshutdownNow时,它只会尝试停止活动线程,它会根据 Java 文档返回活动任务列表:

尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。

此方法不等待主动执行的任务终止。 使用 {awaitTermination} 来做到这一点。

正如文档所说,您需要调用awaitTermination以确保每个线程都已完成,否则此方法将在超时结束时杀死它们。

更新:

如果您不知道时间估计,您可以添加以下几行以确保所有线程都已成功完成。

int filesCount = getFileCount();//you know the files count, right?
AtomicInteger finishedFiles = new AtomicInteger(0);
ExecutorService executorService = Executors.newFixedThreadPool(threadCount);
for (int i = 0; i < threadCount; i++)
    executorService.submit(() -> {
        //do you work
        //at the end of each file process
        finishedFiles.incrementAndGet();
    }
while (finishedFiles.get() < filesCount) { //let's wait until all files have been processed 
    Thread.sleep(100);
}
executorService.shutdown();
executorService.awaitTermination(1, TimeUnit.MINUTES);//anyway they already should have finished 

这是我更新的代码。我已将其从 Future 更改为 FutureTask 并添加了一些行项。 我希望所有这 10 个任务并行运行。

List<FutureTask<Runnable>> futures = new ArrayList<FutureTask<Runnable>>();

    for (int n = 0; n < 10; n++)
    {
        FutureTask f = (FutureTask) service.submit(new Task(n));
        futures.add(f);
    }

    // wait for all tasks to complete before continuing
   // for (FutureTask<Runnable> f : futures)
    for (int i=0; i< futures.size(); i++)
    {
       FutureTask f = (FutureTask)futures.get(i) ;
        //System.out.println("Number of futureTasks: " + i);
        try {


            if(!f.isDone()){
                //wait indefinitely for future task to complete
                f.get();
                //System.out.println("FutureTask output="+f.get());
            }else{
                System.out.println("Task number :" + i + "Done.");
            }

        } catch (InterruptedException | ExecutionException e) {
            System.out.println("Exiting with InterruptedException : " + e.getMessage());
            e.printStackTrace();
        }
    }
 //If we come out from the loop, we must have completed all the tasks. e.e. In above case , 10 tasks ( 10 loop submites)
    try {
        if (!service.awaitTermination(10000000, TimeUnit.MICROSECONDS)) {
            System.out.println("Exiting normally...");
            service.shutdownNow();
            System.exit(0);
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if(!service.isShutdown()){
        System.exit(0);
    }

暂无
暂无

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

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