可通过 while 循环调用
Callable with while loop
我需要提供使用 ExecutorService、Callable 和 Future 进行一些计算并打印部分结果直到达到定义条件的代码。我首先想到的是使用 while 循环。不幸的是,据我所知 ExecutorService.get() 等到任务完成,所以我不能做类似(伪代码)的事情:
public Object call() throws Exception {
try {
while(!condition) {
//perform calc
return partialCalculationResult;
}
}
catch(InterruptedException e){
}
}
谁能指导我正确的方向是什么?
肮脏的选项是在 while 循环中放置一个 System.out.println
。
更简洁的选项是 publish/subscriber 模式,例如:
interface Subscriber {
void onPartialResult(double partialResult);
}
class SystemOutSubscriber implements Subscriber{
@Override
void onPartialResult(double partialResult) {
System.out.println(partialResult);
}
}
class YourCalculatorClass {
List<Subscriber> subscribers = ...
public Object call() throws Exception {
while(!condition) {
//perform calc
for(Subscriber s : subscribers) {
s.onPartialResult(partialCalculationResult);
}
}
}
}
这里是:
while(!condition) {
//perform calc
return partialCalculationResult;
}
表示您的逻辑中有一个"hole"。这可能应该是这样的:
while(!condition) {
// perform computation
push intermediate results somewhere
}
return finalResult;
换句话说:您在这里谈论 两个 不同的元素。对于那些 "progress" 更新,您将需要某种共享数据结构;例如 Queue。
你看,与其他语言不同,没有内置的 "generator" 概念可以让你从循环中 yield 值;例如,就像您在 python or scala 中所做的那样。
您可以使用 Thread.interrupt 停止 while 循环内的线程并将剩余结果添加到列表中
while(!condition){ list.add(addResultHere)
Thread.interrupt(); }
下面是一个使用 ExecutorService
的小例子
推送可调用任务。为了示例的方便,我现在将它们放在一个 while 循环中,但它们可以来自任何地方。 callable 本身当然使用了最简单的例子,它接受一个数字。如果数字低于 5,一切都很好,我们 return 一个文本。如果没有,我们 return 什么都没有。当评估未来并且结果为空时,我们关闭 ExecutorService 并结束它。因此,这是一个使用 ExecutorService
、Callable
和 Future
来做一些事情的示例,至少与我从您的解释中可以看出的内容相似。
public ExecutorServiceTest() {
ExecutorService service = Executors.newCachedThreadPool();
int num = 0;
while (true) {
Future<Optional<String>> future = service.submit(new MyCallable(num++));
try {
Optional<String> result = future.get();
if (!result.isPresent()) {
service.shutdown();
break;
}
System.out.println(result.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
service.shutdown();
}
}
}
private static class MyCallable implements Callable<Optional<String>> {
private final int num;
MyCallable(int num) {
this.num = num;
}
@Override
public Optional<String> call() throws Exception {
if (num < 5)
return Optional.of("My number is " + num);
return Optional.empty();
}
}
public static void main(String[] args) {
new ExecutorServiceTest();
}
我需要提供使用 ExecutorService、Callable 和 Future 进行一些计算并打印部分结果直到达到定义条件的代码。我首先想到的是使用 while 循环。不幸的是,据我所知 ExecutorService.get() 等到任务完成,所以我不能做类似(伪代码)的事情:
public Object call() throws Exception {
try {
while(!condition) {
//perform calc
return partialCalculationResult;
}
}
catch(InterruptedException e){
}
}
谁能指导我正确的方向是什么?
肮脏的选项是在 while 循环中放置一个 System.out.println
。
更简洁的选项是 publish/subscriber 模式,例如:
interface Subscriber {
void onPartialResult(double partialResult);
}
class SystemOutSubscriber implements Subscriber{
@Override
void onPartialResult(double partialResult) {
System.out.println(partialResult);
}
}
class YourCalculatorClass {
List<Subscriber> subscribers = ...
public Object call() throws Exception {
while(!condition) {
//perform calc
for(Subscriber s : subscribers) {
s.onPartialResult(partialCalculationResult);
}
}
}
}
这里是:
while(!condition) {
//perform calc
return partialCalculationResult;
}
表示您的逻辑中有一个"hole"。这可能应该是这样的:
while(!condition) {
// perform computation
push intermediate results somewhere
}
return finalResult;
换句话说:您在这里谈论 两个 不同的元素。对于那些 "progress" 更新,您将需要某种共享数据结构;例如 Queue。
你看,与其他语言不同,没有内置的 "generator" 概念可以让你从循环中 yield 值;例如,就像您在 python or scala 中所做的那样。
您可以使用 Thread.interrupt 停止 while 循环内的线程并将剩余结果添加到列表中
while(!condition){ list.add(addResultHere) Thread.interrupt(); }
下面是一个使用 ExecutorService
的小例子
推送可调用任务。为了示例的方便,我现在将它们放在一个 while 循环中,但它们可以来自任何地方。 callable 本身当然使用了最简单的例子,它接受一个数字。如果数字低于 5,一切都很好,我们 return 一个文本。如果没有,我们 return 什么都没有。当评估未来并且结果为空时,我们关闭 ExecutorService 并结束它。因此,这是一个使用 ExecutorService
、Callable
和 Future
来做一些事情的示例,至少与我从您的解释中可以看出的内容相似。
public ExecutorServiceTest() {
ExecutorService service = Executors.newCachedThreadPool();
int num = 0;
while (true) {
Future<Optional<String>> future = service.submit(new MyCallable(num++));
try {
Optional<String> result = future.get();
if (!result.isPresent()) {
service.shutdown();
break;
}
System.out.println(result.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
service.shutdown();
}
}
}
private static class MyCallable implements Callable<Optional<String>> {
private final int num;
MyCallable(int num) {
this.num = num;
}
@Override
public Optional<String> call() throws Exception {
if (num < 5)
return Optional.of("My number is " + num);
return Optional.empty();
}
}
public static void main(String[] args) {
new ExecutorServiceTest();
}