我正在尝试在Java8中探索CompletableFuture,我写了这个简单的例子来使用假的api但我得到了这个编译错误,我在这段代码周围添加了try / catch块但是我仍然得到相同的编译错误。
* FakeAPI1 *
package com.fake.api;
public class FakeAPI1 implements FakeAPI{
@Override
public void consume(){
try{
Thread.sleep(1000L);
System.out.println("Hello from FakeAPI1");
}catch(InterruptedException e){
System.out.println("Eat it silently");
}
}
public String getRandomText(){
System.out.println("getRandomText() @ FakeAPI1 was called ");
try{
Thread.sleep(1000L);
return "Hello from FakeAPI1";
}catch(InterruptedException e){
System.out.println("Eat it silently");
}
return "Default message from FakeAPI1";
}
}
* CompletableFutureTest *
package com.example.completablefuture;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import com.fake.api.FakeAPI1;
public class CompletableFutureTest {
public static void main(String[] args)
throws InterruptedException,ExecutionException {
List<Future<FakeAPI1>> apis=
Arrays.asList(
new CompletableFuture<FakeAPI1>(),
new CompletableFuture<FakeAPI1>(),
new CompletableFuture<FakeAPI1>()
);
Long start= System.currentTimeMillis();
apis.stream()
//Compilation error is in the line below
//Unhandled exception type ExecutionException
.map(api->api.get().getRandomText())
.collect(Collectors.toList());
Long end= System.currentTimeMillis();
System.out.println("CompletableFutureTest took " + (end-start) + " ms" );
}
}
我在下面的答案中按照建议添加了try / catch块,编译错误不再显示,但是当我运行代码时它没有做任何事情,似乎它正在等待某些东西......
package com.example.completablefuture;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.stream.Collectors;
import com.fake.api.FakeAPI1;
public class CompletableFutureTest {
public static void main(String[] args)
throws InterruptedException,ExecutionException {
List<CompletableFuture<FakeAPI1>> apis=
Arrays.asList(
new CompletableFuture<FakeAPI1>(),
new CompletableFuture<FakeAPI1>(),
new CompletableFuture<FakeAPI1>()
);
Long start= System.currentTimeMillis();
List<String> result= apis.stream()
.map(api-> {
try {
System.out.println("1");
api.get().getRandomText();
}catch (ExecutionException e) {
// TODO: return something else or throw a runtime exception
System.out.println("ExecutionException");
}catch(InterruptedException e){
// TODO: return something else or throw a runtime exception
System.out.println("InterruptedException");
}
return "NA";
})
.collect(Collectors.toList());
result.stream()
.forEach(System.out::println);
Long end= System.currentTimeMillis();
System.out.println("CompletableFutureTest took " + (end-start) + " ms" );
}
}
我在get()方法中添加了一个Timeout参数,并开始抛出InterruptedException
package com.example.completablefuture;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.stream.Collectors;
import com.fake.api.FakeAPI1;
public class CompletableFutureTest {
public static void main(String[] args)
throws InterruptedException,ExecutionException {
List<CompletableFuture<FakeAPI1>> apis=
Arrays.asList(
new CompletableFuture<FakeAPI1>(),
new CompletableFuture<FakeAPI1>(),
new CompletableFuture<FakeAPI1>()
);
Long start= System.currentTimeMillis();
List<String> result= apis.stream()
.map(api-> {
try {
System.out.println("about to call get() method ...");
api.get(1000L, TimeUnit.MILLISECONDS).getRandomText();
}catch (ExecutionException e) {
// TODO: return something else or throw a runtime exception
System.out.println("ExecutionException");
}catch(InterruptedException e){
// TODO: return something else or throw a runtime exception
System.out.println("InterruptedException");
}catch(TimeoutException e){
// TODO: return something else or throw a runtime exception
System.out.println("InterruptedException");
}
return "NA";
})
.collect(Collectors.toList());
result.stream()
.forEach(System.out::println);
Long end= System.currentTimeMillis();
System.out.println("CompletableFutureTest took " + (end-start) + " ms" );
}
}
about to call get() method ...
InterruptedException
about to call get() method ...
InterruptedException
about to call get() method ...
InterruptedException
NA
NA
NA
CompletableFutureTest took 3062 ms
答案 0 :(得分:2)
您没有在正确的地方捕捉到异常。 map()
需要Function。并且函数不能抛出任何已检查的异常。所以你需要
.map(api-> {
try {
return api.get().getRandomText());
}
catch (ExecutionException e) {
// TODO: return something else or throw a runtime exception
}
})
答案 1 :(得分:1)
使用CompletableFuture
时,您应使用join()
方法而不是get()
。它们在功能上是相同的(在非特殊情况下),但前者不会抛出已检查的异常。