In Java, it is only possible to capture final (or effectively final) variables in lambda expressions. It is possible to declare a final variable first and then initialize it once, but not if the initialization occurs in a lambda expression. This is ok:
final int num;
num = 10;
But this is not:
final int num;
Thread thread = new Thread(() -> {
num = 10;
});
thread.start();
Even if run() is used which doesn't create new threads, it doesn't compile, neither will any other lambda expression. This makes sense since you could execute lambda expressions multiple times, which would mean trying to reassign a final variable.
But it seems like it could be useful to initialize variables in a lambda expression e.g. Maybe you have some long process to get and store a value in a variable like reading a large file; but because it is long, you want it to happen in a new thread, so the current one can move on.
The only solution I know is to define the variable as a one-element array, which allows you to change the element. This seems to me somewhat unintuitive and like a way to cheat the language instead of writing good code. Are there better designs which are good for attacking this problem?
The best fit for your example is to submit()
a Callable
to an ExecutorService
. Later, when you need the result, you access it via the resulting Future
.
Alternatively, if the result is not needed in the main thread, and can be handled asynchronously, you can compose a CompletableFuture
to perform your task.