A Future is a class that represents the result of an asynchronous operation. Future can be used to pass some data processed in a multi-threaded environment to another thread.
Because Future is implemented to be thread-safe internally, there is no need to use synchronized block
.
An example makes it easier to understand.
Simple Future Example
In the example below, two Threads are created, and data processed in one thread is transferred to another thread using Future.
ExecutorService executor
= Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
System.out.println(LocalTime.now() + " Starting runnable");
Integer sum = 1 + 1;
Thread.sleep(3000);
return sum;
});
System.out.println(LocalTime.now() + " Waiting the task done");
Integer result = future.get();
System.out.println(LocalTime.now() + " Result : " + result);
ExecutorService
creates a single thread. If a Callable is passed tosubmit()
, the Callable passed as an argument is executed.- A Future object is returned when executor.submit() is called. but the value is not set yet
- future.get() waits for some value to be set in the Future object. If the Callable passed to
submit()
returns a value, that value is set in the Future.
Callable is an interface that takes no arguments but returns some data. Runnable is an interface that takes no arguments and returns no data.
The execution result is as follows.
01:18:18.347 Starting runnable
01:18:18.347 Waiting the task done
01:18:21.348 Result : 2
Another Future example
The example above is simple, but it doesn`t show how the Future is created and how the data is stored.
You can check these parts by looking at the following example.
CompletableFuture<Integer> future
= new CompletableFuture<>();
Executors.newCachedThreadPool().submit(() -> {
System.out.println(LocalTime.now() + " Doing something");
Integer sum = 1 + 1;
Thread.sleep(3000);
future.complete(sum);
return null;
});
System.out.println(LocalTime.now() + " Waiting the task done");
Integer result = future.get();
System.out.println(LocalTime.now() + " Result : " + result);
CompletableFuture<Integer>
to create a Future object. It is implemented as Generics and specifies the data type to be saved.Executors.newCachedThreadPool()
creates a thread pool, and if you pass a callable tosubmit()
, it is executed from the waiting thread- Save data to pass to another thread with
future.complete(data)
- Wait for data to be set with
future.get()
The execution result is as follows.
01:23:54.929 Doing something
01:23:54.929 Waiting the task done
01:23:57.930 Result : 2
Set Timeout to Future.get()
If data is not set in Future
, the thread that called Future.get()
waits indefinitely. Then the program becomes unresponsive.
You can set a Timeout in Future.get()
to return if there is no response within a certain amount of time to handle the next operation.
To set Timeout, pass timeout and TimeUnit, the unit of time, together to get()
as shown below.
Future.get(long timeout, TimeUnit unit)
The following is an example of applying Timeout.
ExecutorService executor
= Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
System.out.println(LocalTime.now() + " Starting runnable");
Integer sum = 1 + 1;
Thread.sleep(4000);
System.out.println(LocalTime.now() + " Exiting runnable");
return sum;
});
System.out.println(LocalTime.now() + " Waiting the task done");
Integer result = null;
try {
result = future.get(2000, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
System.out.println(LocalTime.now() + " Timed out");
result = 0;
}
System.out.println(LocalTime.now() + " Result : " + result);
get(2000, TimeUnit.MILLISECONDS)
means set 2000ms to Timeout. You can also change TimeUnit to SECONDS etc.- If a timeout occurs, a
TimeoutException
exception is thrown. Exception handling is required withtry-catch
The execution result of the above code is as follows.
11:55:06.693 Waiting the task done
11:55:06.693 Starting runnable
11:55:08.696 Timed out
11:55:08.696 Result : 0
11:55:10.696 Exiting runnable
Related Posts
- Java - Remove items from List while iterating
- Java - How to find key by value in HashMap
- Java - Update the value of a key in HashMap
- Java - How to put quotes in a string
- Java - How to put a comma (,) after every 3 digits
- BiConsumer example in Java 8
- Java 8 - Consumer example
- Java 8 - BinaryOperator example
- Java 8 - BiPredicate Example
- Java 8 - Predicate example
- Java 8 - Convert Stream to List
- Java 8 - BiFunction example
- Java 8 - Function example
- Java - Convert List to Map
- Exception testing in JUnit
- Hamcrest Collections Matcher
- Hamcrest equalTo () Matcher
- AAA pattern of unit test (Arrange/Act/Assert)
- Hamcrest Text Matcher
- Hamcrest Custom Matcher
- Why Junit uses Hamcrest
- Java - ForkJoinPool
- Java - How to use Futures
- Java - Simple HashTable implementation
- Java - Create a file in a specific path
- Java - Mockito의 @Mock, @Spy, @Captor, @InjectMocks
- Java - How to write test code using Mockito
- Java - Synchronized block
- Java - How to decompile a ".class" file into a Java file (jd-cli decompiler)
- Java - How to generate a random number
- Java - Calculate powers, Math.pow()
- Java - Calculate the square root, Math.sqrt()
- Java - How to compare String (==, equals, compare)
- Java - Calculate String Length
- Java - case conversion & comparison insensitive (toUpperCase, toLowerCase, equalsIgnoreCase)