Reputation: 10122
Given I have a function in Java which has to do a lot of work. This work consists of several different things to do, which are defined in their own functions and are independent of each other.
void myFunction() {
foo();
bar();
}
However, these functions run one after the other (just as I coded it), which is not necessary here and makes the whole function run longer than necessary. Running both functions in its own thread requires significantly more code:
void myFunction() {
UncaughtExceptionHandler eh = (th, t) -> { throw new UndeclaredThrowableException(t); };
try {
Thread foo = new Thread(() -> foo());
Thread bar = new Thread(() -> bar());
foo.setUncaughtExceptionHandler(eh);
bar.setUncaughtExceptionHandler(eh);
foo.start();
bar.start();
foo.join();
bar.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
So I wonder if there is some built-in approach in newer Java versions to do this more efficiently, something like:
Threads.doParallel(
() -> foo(),
() -> bar()
);
Upvotes: 4
Views: 142
Reputation: 11310
The shortest I get, using CompletableFutures is this :
CompletableFuture.allOf(
CompletableFuture.runAsync(new FutureTask<Void>(() -> foo(), null)),
CompletableFuture.runAsync(new FutureTask<Void>(() -> bar(), null))
).get();
This doesn't have the handling for excptions in foo()
or bar()
. But we can add that, sacrificing some brevity :
CompletableFuture.allOf(
CompletableFuture.runAsync(new FutureTask<Void>(() -> foo(), null)),
CompletableFuture.runAsync(new FutureTask<Void>(() -> bar(), null))
)
.exceptionally(t -> {
throw new UndeclaredThrowableException(t);
})
.get();
Upvotes: 3
Reputation: 409
Here is an example using CompletionService which could run tasks concurrently and collect the results as they become ready.
public void doParallel() {
Executor executor = Executors.newCachedThreadPool();
CompletionService<Boolean> completionService = new ExecutorCompletionService<>(executor);
Future future1 = completionService.submit( () -> foo() );
Future future2 = completionService.submit( () -> bar() );
try {
completionService.take();
completionService.take(); // second task
} catch ( InterruptedException e ) {
e.printStackTrace();
} finally {
future1.cancel( true );
future2.cancel( true );
}
}
Upvotes: 1
Reputation: 33442
Use ExecutorService
:
final ExecutorService executor = Executors.newFixedThreadPool(10);
final Runnable foo = () -> ...;
final Runnable bar = () -> ...;
executor.submit(foo);
executor.submit(bar);
executor.shutdown();
Upvotes: 2