Java ExecutorService - 监控任务Completion/Status 吧
Java ExecutorService - Monitor Task Completion/Status bar
所以我有一个 ExecutorService 成功阻塞并且 运行 现在是线性的。我的麻烦是,我正在尝试添加状态更新,但我不知道如何让 Futures 一次结算一个项目。似乎当我的 Future<> 中的第一项准备就绪时,最后一项也准备好了。我希望找到一个可以知道我的 executorService 有多少任务的地方 remaining/total ,这样我就可以计算一个简单的百分比指标。请注意我打算回收我的 Executor 并且不想关闭它。
ExecutorService updateService = Executors.newSingleThreadExecutor();
Callable<String> callHour = () -> {
//doStuff, unaware of total number of hourCalls
return "done";
};
private void startMe(int hours){
List<Future<String>> futureHours;
List<Callable<String>> hourCalls = new ArrayList<>(hours);
for (int hour = 0; hour < hours; ++hour) {
hourCalls.add(callHour); //queue list (not running yet)
}
try {
//executes queue and blocks thread
futureHours = updateService.invokeAll(hourCalls);
futureHours.get(0).get();//performs blocking
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里有两件事在起作用。
首先,如果我们看一下 the documentation of ExecutorService#invokeAll(...)
,我们会发现它 returns
[...] a list of Futures holding their status and results when all complete. [...]
(重点是我加的)
您很可能想改用 Executor#submit(...)。
其次,你不能保证耦合到futureHours.get(0)
的任务首先执行。我建议使用 Future#isDone()
和一些额外的逻辑:
private void startMe(int hours) {
[...]
try {
[...]
ArrayList<Future<String>> futureHoursDone = new ArrayList<>();
final int numTasks = futureHours.size();
int done = 0;
double percentageDone = 0.0d;
while (futureHours.isEmpty() == false) {
for (int index = 0; index < futureHours.size(); ++index) {
Future<String> futureHour = futureHours.get(index);
if (futureHour.isDone()) {
futureHours.remove(index);
futureHoursDone.add(futureHour);
--index;
++done;
percentageDone = done / (double) numTasks;
}
}
}
} catch (Exception e) {
// TODO: don't forget to HCF (https://en.wikipedia.org/wiki/Halt_and_Catch_Fire) :)
e.printStackTrace();
}
}
(这是一个粗略的草图。要取得进展,即 percentage
,对外部可见,您必须将其设为属性并可通过例如某些 getter 访问)
所以我有一个 ExecutorService 成功阻塞并且 运行 现在是线性的。我的麻烦是,我正在尝试添加状态更新,但我不知道如何让 Futures 一次结算一个项目。似乎当我的 Future<> 中的第一项准备就绪时,最后一项也准备好了。我希望找到一个可以知道我的 executorService 有多少任务的地方 remaining/total ,这样我就可以计算一个简单的百分比指标。请注意我打算回收我的 Executor 并且不想关闭它。
ExecutorService updateService = Executors.newSingleThreadExecutor();
Callable<String> callHour = () -> {
//doStuff, unaware of total number of hourCalls
return "done";
};
private void startMe(int hours){
List<Future<String>> futureHours;
List<Callable<String>> hourCalls = new ArrayList<>(hours);
for (int hour = 0; hour < hours; ++hour) {
hourCalls.add(callHour); //queue list (not running yet)
}
try {
//executes queue and blocks thread
futureHours = updateService.invokeAll(hourCalls);
futureHours.get(0).get();//performs blocking
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里有两件事在起作用。
首先,如果我们看一下 the documentation of ExecutorService#invokeAll(...)
,我们会发现它 returns
[...] a list of Futures holding their status and results when all complete. [...]
(重点是我加的)
您很可能想改用 Executor#submit(...)。
其次,你不能保证耦合到futureHours.get(0)
的任务首先执行。我建议使用 Future#isDone()
和一些额外的逻辑:
private void startMe(int hours) {
[...]
try {
[...]
ArrayList<Future<String>> futureHoursDone = new ArrayList<>();
final int numTasks = futureHours.size();
int done = 0;
double percentageDone = 0.0d;
while (futureHours.isEmpty() == false) {
for (int index = 0; index < futureHours.size(); ++index) {
Future<String> futureHour = futureHours.get(index);
if (futureHour.isDone()) {
futureHours.remove(index);
futureHoursDone.add(futureHour);
--index;
++done;
percentageDone = done / (double) numTasks;
}
}
}
} catch (Exception e) {
// TODO: don't forget to HCF (https://en.wikipedia.org/wiki/Halt_and_Catch_Fire) :)
e.printStackTrace();
}
}
(这是一个粗略的草图。要取得进展,即 percentage
,对外部可见,您必须将其设为属性并可通过例如某些 getter 访问)