ExecutorService、Future、Threads在所有Runnables必须完成时出现Actives
ExecutorService, Future, Threads appears Actives when all Runnables must be finished
我有一个复杂的程序,使用 运行nable、ExecutorService 和 Future。
我想知道为什么Runnable/Threads会出现运行ning,而我的申请还在运行ning,我希望他们必须完成。
完整代码您可以复制和粘贴,运行,您需要的都在这里。
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestFutureExecutorService {
public static void main(String... args) {
List<Future<?>> futureList = new ArrayList<>();
ExecutorService executorService = Executors.newCachedThreadPool();
RunnableTest rt = new RunnableTest("rt", futureList, executorService);
new Timer(false).schedule(new TimerTask() {
@Override
public void run() {
rt.stop();
}
}, ThreadLocalRandom.current().nextLong(100L, 500L));
System.out.println("Let's go to check the threads status.\n");
for (int i = 0; i < futureList.size(); i++) {//Working!
try {
if (futureList.get(i) != null) {
futureList.get(i).get();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Apparently everything is finished.\n");
boolean allDone = true;
for (int i = 0; i < futureList.size(); i++) {
if (futureList.get(i) != null) {
allDone &= futureList.get(i).isDone(); // check if future is done
}
}
System.out.println("Is everything really finished?:" + allDone + ".\n");
//executorService.shutdown();
Thread thisThread = Thread.currentThread();
thisThread.setName("Admin Thread");
thisThread.setPriority(1);
System.out.println("Thread = " + thisThread);
int count = Thread.activeCount();
System.out.println("currently active threads = " + count);
Thread activeThreadsArray[] = new Thread[count];
Thread.enumerate(activeThreadsArray);
// prints active threads
for (int i = 0; i < count; i++) {
System.out.println(i + ": " + activeThreadsArray[i]);
}
}
public static class RunnableTest implements Runnable {
private final String name;
private final List<Future<?>> futureList;
private final ExecutorService executorService;
private volatile boolean isRunning = false;
public RunnableTest(String name, List<Future<?>> futureList, ExecutorService executorService) {
this.name = name;
this.futureList = futureList;
this.executorService = executorService;
this.futureList.add(this.executorService.submit(this));
}
@Override
public void run() {
Thread.currentThread().setName(Thread.currentThread().getName() + this.getClass().getSimpleName() + ":" + name);
isRunning = true;
while (isRunning) {
try {
Thread.sleep(50);
new Processor(this.futureList, this.executorService);
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("Finishing:" + Thread.currentThread().getName());
}
public void stop() {
isRunning = false;
}
}
public static class Processor implements Runnable {
private final List<Future<?>> futureList;
private final ExecutorService executorService;
public Processor(List<Future<?>> futureList, ExecutorService executorService) {
this.futureList = futureList;
this.executorService = executorService;
this.futureList.add(this.executorService.submit(this));
}
@Override
public void run() {
String hour = new SimpleDateFormat("_yyyyMMdd-HHmmss.SSSS_").format(new Date());
Thread.currentThread().setName(hour + this.getClass().getSimpleName());
try {
int timeSleeping = ThreadLocalRandom.current().nextInt(100, 300);
Thread.sleep(timeSleeping);
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Finishing:" + Thread.currentThread().getName());
}
}
}
现在,输出....
Let's go to check the threads status.
Finishing:_20190923-203808.0435_Processor
Finishing:_20190923-203808.0437_Processor
Finishing:_20190923-203808.0489_Processor
Finishing:pool-1-thread-1->RunnableTest:rt
Finishing:_20190923-203808.0695_Processor
Finishing:_20190923-203808.0544_Processor
Finishing:_20190923-203808.0593_Processor
Finishing:_20190923-203808.0746_Processor
Finishing:_20190923-203808.0645_Processor
Apparently everything is finished.
Is everything really finished?:true.
Thread = Thread[Admin Thread,1,main]
currently active threads = 8
0: Thread[Admin Thread,1,main]
1: Thread[pool-1-thread-1->RunnableTest:rt,5,main]
2: Thread[Timer-0,5,main]
3: Thread[_20190923-203808.0593_Processor,5,main]
4: Thread[_20190923-203808.0695_Processor,5,main]
5: Thread[_20190923-203808.0746_Processor,5,main]
6: Thread[_20190923-203808.0544_Processor,5,main]
7: Thread[_20190923-203808.0645_Processor,5,main]
当我运行申请的时候,在我的IDE里,还留着一些东西"running",但是所有运行nable都必须完成!
为什么线程显示为活动状态? 这是什么意思?
如何全部完成?
您正在使用 ExecutorService。 ExecutorService 使线程保持活动状态,以便为下一个任务做好准备。您必须告诉 ExecutorService 您不再有任务,它可以丢弃线程。
您可以通过调用方法来完成此操作
`shutdown() or shutdownNow()`
因此在完成检查后取消注释代码中的行:
System.out.println("Is everything really finished?:" + allDone + ".\n");
//executorService.shutdown();
您的应用程序仍然不会完成,因为您将计时器线程创建为非守护线程,这意味着如果您的应用程序中存在 运行 个非守护线程,JVM 将不会停止。
您可以像这样将计时器创建为守护线程:
new Timer(true).schedule(new TimerTask() {
我有一个复杂的程序,使用 运行nable、ExecutorService 和 Future。
我想知道为什么Runnable/Threads会出现运行ning,而我的申请还在运行ning,我希望他们必须完成。
完整代码您可以复制和粘贴,运行,您需要的都在这里。
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TestFutureExecutorService {
public static void main(String... args) {
List<Future<?>> futureList = new ArrayList<>();
ExecutorService executorService = Executors.newCachedThreadPool();
RunnableTest rt = new RunnableTest("rt", futureList, executorService);
new Timer(false).schedule(new TimerTask() {
@Override
public void run() {
rt.stop();
}
}, ThreadLocalRandom.current().nextLong(100L, 500L));
System.out.println("Let's go to check the threads status.\n");
for (int i = 0; i < futureList.size(); i++) {//Working!
try {
if (futureList.get(i) != null) {
futureList.get(i).get();
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
System.out.println("Apparently everything is finished.\n");
boolean allDone = true;
for (int i = 0; i < futureList.size(); i++) {
if (futureList.get(i) != null) {
allDone &= futureList.get(i).isDone(); // check if future is done
}
}
System.out.println("Is everything really finished?:" + allDone + ".\n");
//executorService.shutdown();
Thread thisThread = Thread.currentThread();
thisThread.setName("Admin Thread");
thisThread.setPriority(1);
System.out.println("Thread = " + thisThread);
int count = Thread.activeCount();
System.out.println("currently active threads = " + count);
Thread activeThreadsArray[] = new Thread[count];
Thread.enumerate(activeThreadsArray);
// prints active threads
for (int i = 0; i < count; i++) {
System.out.println(i + ": " + activeThreadsArray[i]);
}
}
public static class RunnableTest implements Runnable {
private final String name;
private final List<Future<?>> futureList;
private final ExecutorService executorService;
private volatile boolean isRunning = false;
public RunnableTest(String name, List<Future<?>> futureList, ExecutorService executorService) {
this.name = name;
this.futureList = futureList;
this.executorService = executorService;
this.futureList.add(this.executorService.submit(this));
}
@Override
public void run() {
Thread.currentThread().setName(Thread.currentThread().getName() + this.getClass().getSimpleName() + ":" + name);
isRunning = true;
while (isRunning) {
try {
Thread.sleep(50);
new Processor(this.futureList, this.executorService);
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("Finishing:" + Thread.currentThread().getName());
}
public void stop() {
isRunning = false;
}
}
public static class Processor implements Runnable {
private final List<Future<?>> futureList;
private final ExecutorService executorService;
public Processor(List<Future<?>> futureList, ExecutorService executorService) {
this.futureList = futureList;
this.executorService = executorService;
this.futureList.add(this.executorService.submit(this));
}
@Override
public void run() {
String hour = new SimpleDateFormat("_yyyyMMdd-HHmmss.SSSS_").format(new Date());
Thread.currentThread().setName(hour + this.getClass().getSimpleName());
try {
int timeSleeping = ThreadLocalRandom.current().nextInt(100, 300);
Thread.sleep(timeSleeping);
} catch (Exception ex) {
Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Finishing:" + Thread.currentThread().getName());
}
}
}
现在,输出....
Let's go to check the threads status.
Finishing:_20190923-203808.0435_Processor
Finishing:_20190923-203808.0437_Processor
Finishing:_20190923-203808.0489_Processor
Finishing:pool-1-thread-1->RunnableTest:rt
Finishing:_20190923-203808.0695_Processor
Finishing:_20190923-203808.0544_Processor
Finishing:_20190923-203808.0593_Processor
Finishing:_20190923-203808.0746_Processor
Finishing:_20190923-203808.0645_Processor
Apparently everything is finished.
Is everything really finished?:true.
Thread = Thread[Admin Thread,1,main]
currently active threads = 8
0: Thread[Admin Thread,1,main]
1: Thread[pool-1-thread-1->RunnableTest:rt,5,main]
2: Thread[Timer-0,5,main]
3: Thread[_20190923-203808.0593_Processor,5,main]
4: Thread[_20190923-203808.0695_Processor,5,main]
5: Thread[_20190923-203808.0746_Processor,5,main]
6: Thread[_20190923-203808.0544_Processor,5,main]
7: Thread[_20190923-203808.0645_Processor,5,main]
当我运行申请的时候,在我的IDE里,还留着一些东西"running",但是所有运行nable都必须完成!
为什么线程显示为活动状态? 这是什么意思?
如何全部完成?
您正在使用 ExecutorService。 ExecutorService 使线程保持活动状态,以便为下一个任务做好准备。您必须告诉 ExecutorService 您不再有任务,它可以丢弃线程。
您可以通过调用方法来完成此操作
`shutdown() or shutdownNow()`
因此在完成检查后取消注释代码中的行:
System.out.println("Is everything really finished?:" + allDone + ".\n");
//executorService.shutdown();
您的应用程序仍然不会完成,因为您将计时器线程创建为非守护线程,这意味着如果您的应用程序中存在 运行 个非守护线程,JVM 将不会停止。
您可以像这样将计时器创建为守护线程:
new Timer(true).schedule(new TimerTask() {