java多线程执行程序永不关闭线程

问题描述 投票:0回答:2

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

对于小过程,它工作正常,但是在完成大过程后,不退出程序。

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

此程序的目的是从数据库中获取数据,转到云中读取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();
    }

 }
}
java multithreading executorservice
2个回答
0
投票

这是我更新的代码。我将其从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);
    }

0
投票

这是因为当您在shutdown上调用shutdownNowexecutorService时,它仅尝试停止活动线程,并且它将根据Java文档返回活动任务列表:

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

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

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

UPDATE:

如果您不了解时序估计,则可以添加以下几行以确保所有线程都已成功完成。

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 
© www.soinside.com 2019 - 2024. All rights reserved.