Callable Interface and Interface Detailed Futrue

Callable Interface

There are two ways to create threads - one is by creating a Thread class, and the other is through the use of Runnable create threads. However, Runnable one feature missing is (ie run () to complete) when the thread terminates, we can not make the thread return results. To support this functionality, Java provides Callable interface.

  • In order to achieve the Runnable, returns nothing need to implement the run () method, and for a Callable, need to implement the call () method returns the result at the time of completion. Please note that you can not use Callable create a thread, the thread can only be used to create Runnable.
  • Another difference is the call () method can throw an exception, and the run () can not.
  • To achieve Callable must override the call method.

     

// Java program to illustrate Callable 
// to return a random number 
import java.util.Random; 
import java.util.concurrent.Callable; 
import java.util.concurrent.FutureTask; 
  
class CallableExample implements Callable 
{ 
  
    public Object call() throws Exception 
    { 
        // Create random number generator 
        Random generator = new Random(); 
  
        Integer randomNumber = generator.nextInt(5); 
  
        // To simulate a heavy computation, 
        // we delay the thread for some random time 
        Thread.sleep(randomNumber * 1000); 
  
        return randomNumber; 
    } 
} 

Futrue Interface

When the call () method is completed, the result must be stored in the main thread known object, so you know that the main thread of the thread is returned. To do this, you can use the Future object. Future results will be stored as an object - it may temporarily save the results, but in the future will be saved (once Callable return). Therefore, Future is basically the main thread can track the progress and results of one way of the other threads. To implement this interface must be rewritten five methods, but due to the following example uses a specific implementation of the library, so this method only lists important.

  • public boolean cancel (boolean mayInterrupt): used to stop the task. If you have not started, it will stop the task. If you have started, it will only interrupt task when mayInterrupt is true.
  • public Object get () throws InterruptedException, ExecutionException: used to obtain the results of the task. If the task is complete, it returns the result immediately, otherwise it will wait for the task to complete, and returns the result.
  • public boolean isDone (): If the task is completed, it returns true, false otherwise

Callable and Future can be seen to do two things -Callable and Runnable similar, because it encapsulates the task to run on a different thread, and the Future for storing results obtained from another thread. In fact, future can also be used with Runnable.

To create a thread, we need to Runnable. In order to get the results, we need future.

FutureTask Java library has a specific type, which implement Runnable and Future, and easily combines two functions.
FutureTask can be created by providing Callable its constructor. Then, the object is supplied to FutureTask Thread constructor to create a Thread object . Therefore, use Callable indirectly create threads.

1. Future and complete example of Callable

Package com.example.thread.callable; 

Import of java.util.ArrayList;
 Import java.util.Date;
 Import java.util.List;
 Import the java.util.concurrent *. ; 

/ ** 
 * @author : GuanBin 
 * @date : created in PM 2019/10/31 11:19 
 * / 
public  class TestCallable the implements a Callable <Object> { 

    Private  int taskNum; 

    public (TestCallable int taskNum) {
         the this .taskNum = taskNum; 
    }     // main difference is created 1,2 thread way
     

public static void main(String[] args) throws ExecutionException, InterruptedException { test1(); test2(); } /** * 使用Executors.newFixedThreadPool创建线程池 * @throws InterruptedException * @throws ExecutionException */ private static void test1() throws InterruptedException, ExecutionException { System.out.println("----程序开始运行----"); Date date1 = new Date(); int taskSize=5; The pool ExecutorService = Executors.newFixedThreadPool (taskSize); List <Future> List = new new the ArrayList <Future> (); for ( int I = 0; I <taskSize; I ++ ) { a Callable C = new new TestCallable (I); // perform Future object task and acquires Future F = pool.submit (C); List.add (F); } // close the thread pool pool.shutdown (); // Get the operation results of all concurrent tasks for (Future F: List) { // Get the return value from the task Future object, and outputs to the console System.out.println ( ">>>" + f.get () toString ().); // the OPTION + return Throws } a Date DATE2 = new new a Date (); System.out.println ( "---- ---- end of program running, running time [ "+ (date2.getTime () - date1.getTime ()) +" milliseconds] " ); } / ** * thread used directly to create a new thread * @throws ExecutionException * @throws InterruptedException * / Private static void test2 () throws ExecutionException, InterruptedException { System.out.println ( "---- ---- program starts to run." ); Date date1 = new Date(); int taskSize=5; FutureTask[] randomNumberTasks = new FutureTask[5]; List<Future> list = new ArrayList<Future>(); for (int i = 0; i < randomNumberTasks.length; i++) { Callable c = new TestCallable(i); // 执行任务并获取Future对象 randomNumberTasks[i]= new FutureTask(c); Thread t = newThe Thread (randomNumberTasks [I]); t.start (); } // get all concurrent tasks run results for (Future F: randomNumberTasks) { // Get the return value from the task Future object and outputting System.out. the println (. ">>>" + f.get () toString ()); // the OPTION + return Throws } a Date DATE2 = new new a Date (); System.out.println ( "end program run ---- - --- the program running time [ "+ (date2.getTime () - date1.getTime ()) +" ms] " ); } / ** * Call implementation of the method, the main thread of execution for the specific implementation, and Back to results * @return * @throws Exception * / @Override public Object Call () throws Exception { System.out.println ( ">>>" + + taskNum "task starts" ); a Date dateTmp1 = new new a Date (); the Thread.sleep ( 1000 ); a Date dateTmp2 = new new a Date (); Long time = dateTmp2.getTime () - dateTmp1.getTime (); System.out.println ( ">>>" taskNum + + "a task termination" ); return taskNum + "running task returns a result, the current task time [ "+ time +" msec] " ; } }

Export

The program starts running ---- ---- 
>>> 0 Task Launcher
 >>> 1 task start
 >>> 2 Task Launcher
 >>> 3 Task Launcher
 >>> 4 Task Launcher
 >>> 0 task termination
 >>> 0 run task returns a result, the current task ms time [1002]
 >>> 1 task terminates
 >>> 2 task terminates
 >>> 4 task terminates
 >>> 1 running task returns a result, the current task ms time [1005]
 >>> 2 task returns the results of running the current task ms time [1005]
 >>> 3 task terminates
 >>> 3 running task returns a result, the current task ms time [1005]
 >>> 4 task returns the results of running the current task time [1005 ms ]
 ---- ---- finished running the program , the program run time in milliseconds [1007] 

Process Finished with Exit code 0

 

2. Callable and complete example of FutureTask

// Java program to illustrate Callable and FutureTask 
// for random number generation 
import java.util.Random; 
import java.util.concurrent.Callable; 
import java.util.concurrent.FutureTask; 
  
class CallableExample implements Callable 
{ 
  
  public Object call() throws Exception 
  { 
    Random generator = new Random(); 
    Integer randomNumber = generator.nextInt(5); 
  
    Thread.sleep(randomNumber * 1000); 
  
    return randomNumber; 
  } 
  
} 
  
public class CallableFutureTest 
{ 
  public static void main(String[] args) throws Exception 
  { 
  
    // FutureTask is a concrete class that 
    // implements both Runnable and Future 
    FutureTask[] randomNumberTasks = new FutureTask[5]; 
  
    for (int i = 0; i < 5; i++) 
    { 
      Callable callable = new CallableExample(); 
  
      // Create the FutureTask with Callable 
      randomNumberTasks[i] = new FutureTask(callable); 
  
      // As it implements Runnable, create Thread 
      // with FutureTask 
      Thread t = new Thread(randomNumberTasks[i]); 
      t.start(); 
    } 
  
    for (int i = 0; i < 5; i++) 
    { 
      // As it implements Future, we can call get() 
      System.out.println(randomNumberTasks[i].get()); 
  
      // This method blocks till the result is obtained 
      // The get method can throw checked exceptions 
      // like when it is interrupted. This is the reason 
      // for adding the throws clause to main 
    } 
  } 
} 

After starting the thread, the thread of all interactions with the use FutureTask, because it implements the Future interface. Thus, no storage Thread object. Use FutureTask object, you can also cancel a job, check the job is done or try to obtain results.

3. Use the Runnable to capture the return of the results achieved

// Java program to illustrate Runnable 
// for random number generation 
import java.util.Random; 
import java.util.concurrent.Callable; 
import java.util.concurrent.FutureTask; 
  
class RunnableExample implements Runnable 
{ 
    // Shared object to store result 
    private Object result = null; 
  
    public void run() 
    { 
        Random generator = new Random(); 
        Integer randomNumber = generator.nextInt(5); 
  
        // As run cannot throw any Exception 
        try
        { 
            Thread.sleep(randomNumber * 1000); 
        } 
        catch (InterruptedException e) 
        { 
            e.printStackTrace(); 
        } 
  
        // Store the return value in result when done 
        result = randomNumber; 
  
        // Wake up threads blocked on the get() method 
        synchronized(this) 
        { 
            notifyAll(); 
        } 
    } 
  
    public synchronized Object get() 
          throws InterruptedException 
    { 
        while (result == null) 
            wait(); 
  
        return result; 
    } 
} 
  
// Code is almost same as the previous example with a 
// few changes made to use Runnable instead of Callable 
public class RunnableTest 
{ 
    public static void main(String[] args) throws Exception 
    { 
        RunnableExample[] randomNumberTasks = new RunnableExample[5]; 
  
        for (int i = 0; i < 5; i++) 
        { 
            randomNumberTasks[i] = new RunnableExample(); 
            Thread t = new Thread(randomNumberTasks[i]); 
            t.start(); 
        } 
  
        for (int i = 0; i < 5; i++) 
            System.out.println(randomNumberTasks[i].get()); 
    } 
} 
 

Guess you like

Origin www.cnblogs.com/guanbin-529/p/11784914.html