我有这样的旧式代码:
ObjectToInstantiate instance = new ObjectToInstantiate();
Thread getFirstValueThread = new Thread(() -> instance.setFirstValue(service.getFirstValue));
Thread getSecondValueThread = new Thread(() -> instance.setSecondValue(service.getSecondValue));
getFirstValueThread.start();
getSecondValueThread.start();
try {
getFirstValueThread.join();
getSecondValueThread.join();
} catch (InterruptedException e) {
throw new RuntimeException(e.getMessage(), e);
}
return instance;
Run Code Online (Sandbox Code Playgroud)
FirstValue和SecondValue是不同的类,我也可以将它们传递给构造函数,而不仅仅是setter.
我怎样才能使用ExecutorService或其他东西来避免新的线程创建?
看看CompletableFutures,它的设计理念是在给定的一段时间后返回值.您也可以轻松管理异常案例.
CompletableFuture<FirstValue> f1 = CompletableFuture.supplyAsync(() -> service.getFirstValue());
CompletableFuture<SecondValue> f2 = CompletableFuture.supplyAsync(() -> service.getSecondValue());
CompletableFuture<ObjectToInstantiate> combineFuture = f1.thenCombine(f2, (firstValue, secondValue) -> new ObjectToInstantiate (firstValue, secondValue));
ObjectToInstantiate myObject = combineFuture .join();
Run Code Online (Sandbox Code Playgroud)
这样做是创建两个返回值的异步线程.f1.thenCombine在成功完成时获取两者的值,并组合两者的值以创建新对象.
您现在不使用方法的副作用,但实际上返回并移动值以创建新对象.
另外,根据您在对象上的构造函数的方式,您可能也可以这样做
f1.thenCombine(f2, ObjectToInstantiate::new);
Run Code Online (Sandbox Code Playgroud)
您也可以为异步方法执行此操作
CompletableFuture.supplyAsync(service::getFirstValue)
Run Code Online (Sandbox Code Playgroud)
此外,如果您已经有执行服务,您可以更改
CompletableFuture.supplyAsync(() -> service.getFirstValue);
Run Code Online (Sandbox Code Playgroud)
至
CompletableFuture.supplyAsync(() -> service.getFirstValue, myExecutorService);
Run Code Online (Sandbox Code Playgroud)