[英]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
上调用shutdown
或shutdownNow
时,它只会尝试停止活动线程,它会根据 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.