Callable
Interface
public interface Callable<V> { V call() throws Exception; }
Test class
import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import java.util.concurrent.Callable; /** * @author syw * @date 2021 22:00, August 25 */ public class CallableTest implements Callable<String> { private String string; public CallableTest(String string) { this.string = string; } @Override public String call() throws Exception { //The task is blocked for 5 seconds, and the exception is thrown upward Thread.sleep(5000); return this.string; } // Exceptions can also be resolved by try catch // @Override // public String call(){ // //The task is blocked for 5 seconds, and the exception is thrown upward // try { // Thread.sleep(5000); // } catch (InterruptedException e) { // e.printStackTrace(); // } // return this.string; // } public static void main(String[] args) throws ExecutionException, InterruptedException { Callable<String> callable = new CallableTest("my callable is ok!"); FutureTask<String> task = new FutureTask<String>(callable); long beginTime = System.currentTimeMillis(); //Create thread new Thread(task).start(); //Call the get() method to block the main thread String str = task.get(); long endTime = System.currentTimeMillis(); System.out.println("hello :"+ str); System.out.println("time :"+ (endTime - beginTime)/1000); } }
Test output: output after an interval of five seconds
Runnable
Interface
public interface Runnable { void run(); }
Test class
public class RunnableTest implements Runnable{ private String str; public RunnableTest(String str) { this.str = str; } @Override public void run() { try { //The thread is dormant for 5s, and an exception occurs. It can only be solved internally and cannot be thrown up Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } //Output after 5s System.out.println("hello:" + this.str); } public static void main(String[] args) { Runnable runnable = new RunnableTest("my runnable is ok"); Long beginTime = System.currentTimeMillis(); Thread thread=new Thread(()->{ runnable.run(); }); thread.start(); Long endTime = System.currentTimeMillis(); //First output System.out.println("time: " + (endTime-beginTime)/1000); } }
Test results:
The difference between the two
1. The biggest difference is that runnable has no return value, while the task thread implementing the callable interface can return the execution result
2. The run method in the callable interface implementation class allows exceptions to be thrown upward and can be handled internally. try catch, but the exceptions of the run method in the runnable interface implementation class must be handled internally and cannot be thrown
Supplementary Executor framework
The Executor framework consists of tasks, task execution, and asynchronous calculation results
- Executor is an interface, which is the basis of executor framework. It separates task Submission from task execution
Come on; - ThreadPoolExecutor is the core implementation class of thread pool, which is used to execute the submitted task;
- ScheduledThreadPoolExecutor is an implementation class that can run commands after a given delay or execute them periodically
Line command. ScheduledThreadPoolExecutor is more flexible and powerful than Timer; - The Future interface and the FutureTask class implementing the Future interface represent the results of asynchronous calculation;
- The implementation classes of Runnable interface and Callable interface can be executed by ThreadPoolExecutor or scheduled ThreadPoolExecutor;
Schematic diagram of frame usage:
Explanation of frame use:
1. The main thread must first create a task object that implements the Runnable or Callable interface. The tool class Executors can put a
A Runnable object is encapsulated as a callable object (Executors.callable (Runnable task) or
Executors.callable(Runnable task,Object resule)).
2. Then you can give the Runnable object directly to ExecutorService (ExecutorService.execute (Runnable
command)); Alternatively, you can submit the Runnable object or Callable object to ExecutorService for execution (ExecutorService.submit (Runnable task) or ExecutorService.submit (Callabletask)).
3. If ExecutorService Submit (...), ExecutorService will return an object that implements the Future interface
(in the JDK so far, the FutureTask object is returned). Since FutureTask implements Runnable, programmers can also
To create FutureTask, and then directly hand it over to ExecutorService for execution.
4. Finally, the main thread can execute futuretask Get () method to wait for the task execution to complete. The main thread can also execute
FutureTask.cancel (boolean mayInterruptIfRunning) to cancel the execution of this task.
... that's all