Original address: http://chenxiaoqiong.com/articles/thread2/
If there is a very time-consuming return value to be calculated, and the return value is not immediately needed, then this combination can be used to calculate the return value with another thread, while the current thread can do other operations before using the return value, and when the return value is needed, it can be obtained through Future.
Create the implementation class of the Callable interface and implement the call() method, which will be the thread execution body with return value.
class MyCallable implements Callable<T> {
...
public T call() throws Exception {
// Write the tasks that the thread needs to complete here
}
}
Create an instance of the Callable implementation class, start the thread and get the return value in two ways:
1. Wrap the Callable object with the FutureTask class, which encapsulates the return value of the call() method of the Callable object. Use the FutureTask object as the target of the Thread object to create and start a new Thread. Call the get() method of the FutureTask object to get the return value after the execution of the child Thread.
Example:
class CallableThreadTest implements Callable<Integer> {
public static void main(String[] args) {
CallableThreadTest ctt = new CallableThreadTest();
FutureTask<Integer> ft = new FutureTask<>(ctt);
new Thread(ft).start();
// Maybe do something else
try {
System.out.println("Return value of child thread:" + ft.get());
} catch (InterruptedException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
@Override
public Integer call() throws Exception {
// Tasks to be completed by threads
return new Random().nextInt(100);
}
2. Use ExecutoreService to provide the submit() method, pass a Callable and return Future.
Example:
class Test {
public static void main(String[] args) throws ExecutionException,
InterruptedException {
System.out.println("----Program start----");
Date date1 = new Date();
int taskSize = 5;
// Create a thread pool
ExecutorService pool = Executors.newFixedThreadPool(taskSize);
// Create multiple tasks with return values
List<Future> list = new ArrayList<>();
for (int i = 0; i < taskSize; i++) {
Callable c = new MyCallable(i + "");
// Execute the task and get the Future object
Future f = pool.submit(c);
list.add(f);
}
// Close thread pool
pool.shutdown();
// Get the running results of all concurrent tasks
for (Future f : list) {
// Get the return value of the task from the Future object and output it to the console
System.out.println(">>>" + f.get().toString());
}
Date date2 = new Date();
System.out.println("----End of program----,Program run time["
+ (date2.getTime() - date1.getTime()) + "MS]");
}
}
class MyCallable implements Callable<Object> {
private String name;
MyCallable(String name) {
this.name = name;
}
public Object call() throws Exception {
System.out.println("Thread:" + name + "Start running");
long time1 = System.currentTimeMillis();
Thread.sleep(1000);
long time2 = System.currentTimeMillis();
return "Thread:" + name + "Running time[" + (time2 - time1) + "]";
}
}
If the Executor background thread pool has not completed the Callable calculation, the call returns the get() method of the Future object, which will block until the calculation is completed.