Callable and Future interfaces
Callable is an interface similar to Runnable. The classes that implement the Callable interface and the classes that implement the Runnable are tasks that can be executed by other threads.
There are several differences between Callable and Runnable:
(1) The method specified by Callable is call(), while the method specified by Runnable is run().
(2) The Callable task can return the value after it is executed, while the Runnable task cannot return the value.
(3) The call() method can throw exceptions, while the run() method cannot throw exceptions.
(4) Run the Callable task and you can get a Future object. Future represents the result of asynchronous calculation.
It provides a method to check whether the calculation is completed, to wait for the calculation to be completed, and to retrieve the results of the calculation.
Through the Future object, you can understand the task execution status, cancel the task execution, and also obtain the results of the task execution.
The code copy is as follows:
package com.yao;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class CallableAndFuture {
/**
* Customize a task class to implement the Callable interface
*/
public static class MyCallableClass implements Callable {
// Logo position
private int flag = 0;
public MyCallableClass(int flag) {
this.flag = flag;
}
public String call() throws Exception {
if (this.flag == 0) {
// If the value of flag is 0, return immediately
return "flag = 0";
}
if (this.flag == 1) {
// If the value of flag is 1, do an infinite loop
try {
while (true) {
System.out.println("looping...");
Thread.sleep(2000);
}
} catch (InterruptedException e) {
System.out.println("Interrupted");
}
return "false";
} else {
// If the false is not 0 or 1, an exception will be thrown
throw new Exception("Bad flag value!");
}
}
}
public static void main(String[] args) {
// Define 3 Callable types tasks
MyCallableClass task1 = new MyCallableClass(0);
MyCallableClass task2 = new MyCallableClass(1);
MyCallableClass task3 = new MyCallableClass(2);
// Create a service that performs tasks
ExecutorService es = Executors.newFixedThreadPool(3);
try {
// Submit and execute the task. When the task starts, a Future object is returned.
// If you want to get the result of task execution or exception, you can operate on this Future object
Future future1 = es.submit(task1);
// Get the result of the first task. If the get method is called, the current thread will wait for the task to be executed before executing it downwards.
System.out.println("task1: " + future1.get());
Future future2 = es.submit(task2);
// Wait for 5 seconds before stopping the second task. Because the second task is an infinite loop
Thread.sleep(5000);
System.out.println("task2 cancel: " + future2.cancel(true));
// Get the output of the third task, because executing the third task will cause an exception
// So the following statement will cause the exception to be thrown
Future future3 = es.submit(task3);
System.out.println("task3: " + future3.get());
} catch (Exception e) {
System.out.println(e.toString());
}
// Stop the task execution service
es.shutdownNow();
}
}