Java Concurrency -CallBack and Future Mode

Callable

  In the Javamiddle, there are two ways to create threads, one is inherited Threadcategories, one is to realize Runnablethe interface. However, the disadvantage of these two methods is that at the end of a thread of execution tasks, the results can not be obtained. We generally only use shared variables or shared memory and thread communication means to achieve the purpose of obtaining results of the task.
  
  However, Javain also provides for the use Callableand Futureoperations to achieve access to the results of the task. CallableTo perform the task, produce results, and Futureto get results.
  
  CallableInterface and Runnablewhether an interface similar to the view source code, we can see Callablethe interface is defined as follows:

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

  It can be seen with Runnablethe interface except that, callthe method having the generic return value V .

FutureCommon method

  • V get() : Getting Results asynchronous execution, if no results are available, this method will block until the asynchronous computation is complete.
  • V get(Long timeout , TimeUnit unit): Get asynchronous execution result, if no results are available, this method will block, but there is a time limit, if the blocking time exceeds the set timeout time, the method throws an exception.
  • boolean isDone(): If the task execution ends, either end or canceled during normal or abnormal, return true.
  • boolean isCanceller() : If canceled before the task is complete, it returns true.
  • boolean cancel(boolean mayInterruptRunning)
    • If the task has not started, execute cancel(...)method returns false;
    • If the task has been started , the implementation of cancel(true)the method will interrupt the task execution thread way to try to stop the task , if you stop successful return true; when the task has been launched , the implementation of cancel(false)the method will have no effect on the task executing thread (thread to perform normal to complete), then returns false;
    • When the task has been completed, the implementation cancel(...)method returns false. mayInterruptRunningParameter indicates whether to interrupt the execution threads.

We also know that by the method of analysis actually Future provides three functions:

  • (1) able to interrupt the task execution
  • If (2) determine the completion of task execution
  • (3) to obtain the amount of task execution results upon completion.

Examples
  
  we use to understand usage Callable and Future tasks to get the results through a simple example.
  

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CalBFutrueTest {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        final Future<String> submit = newCachedThreadPool.submit(new TaskCallback());
        System.out.println(Thread.currentThread().getName()+"-主线程开始执行");
        new Thread(new Runnable() {
            public void run() {
                try {
                    String result = submit.get();
                    System.out.println(result);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        System.out.println("主线程执行任务...");
        if(newCachedThreadPool!=null) {
            //关闭线程池
            newCachedThreadPool.shutdown();
        }
    }
}
class TaskCallback implements Callable<String> {
    public String call() throws Exception {
        System.out.println("子线程正在执行任务,请等待5s");
        Thread.sleep(5000);
        System.out.println("子线程 任务结束");
        return "abab";
    }
}

Results of the

子线程正在执行任务,请等待5s
main-主线程开始执行
主线程执行任务...
子线程 任务结束
abab

Future Mode

  FutureThe core model is that: In addition to the main function of the waiting time, and makes the original time period to wait can be used to deal with other business logic
  Futruremode: For multithreaded, if thread A thread to wait for Bthe result, then the thread Ais no need to wait Buntil Bthere result, you can get a future Future, and so Bthe outcome is and then take real results.

  In a multithreaded often cited example is: network download pictures, beginning to replace the last picture is fuzzy pictures, download pictures and other images threaded download After the replacement. In this process, you can do some other things.  

Future Mode Timing
Future Mode Timing

  First of all client requests to the server RealSubject, but this is very time-consuming to create a resource, and how to do it? In this case, first returned Clienta FutureSubjectto meet the needs of the client, the same time it, Futurewill pass another Threadafter to construct a real resource, resources ready, giving futurea notice. If the client is eager to get this real resource, all other threads will be blocked clients, waiting for a resource ready.

A common data interface, FutureData and RealData must achieve.

public abstract class Data {
    public abstract String getRequest();
}

Real data RealData

public class RealData extends Data {
    private String result;

    public RealData(String data) {
        System.out.println("正在使用data:" + data + "网络请求数据,耗时操作需要等待.");
        try {
            Thread.sleep(3000);
        } catch (Exception e) {}
        System.out.println("操作完毕,获取结果...");
        result = "返回值aaaabb";
    }

    @Override
    public String getRequest() {
        return result;
    }
}

FutureData, when there is a thread wants to acquire RealData, the program will be blocked. It will be injected until RealData used getreal () method.

public class FutureData extends Data {

    public volatile static boolean ISFLAG = false;
    private RealData realData;
    public synchronized void setRealData(RealData realData) {
        // 如果已经获取到结果,直接返回
        if (ISFLAG) {
            return;
        }
        // 如果没有获取到数据,传递真是对象
        this.realData = realData;
        ISFLAG = true;
        // 进行通知
        notify();
    }
    @Override
    public synchronized String getRequest() {
        while (!ISFLAG) {
            try {
                wait();
            } catch (Exception e) {}
        }
        // 获取到数据,直接返回
        return realData.getRequest();
    }
}

FutureClient client

public class FutureClient {
    public Data request(String queryStr) {
        FutureData furureData = new FutureData();
        new Thread(new Runnable() {
            @Override
            public void run() {
                RealData realData = new RealData(queryStr);
                furureData.setRealData(realData);
            }
        }).start();
        return furureData;
    }

}

Caller:

public class Main {
    public static void main(String[] args) {
        FutureClient futureClient = new FutureClient();
        Data request = futureClient.request("请求参数.");
        System.out.println("请求发送成功!");
        System.out.println("执行其他任务...");
        String result = request.getRequest();
        System.out.println("获取到结果..." + result);
    }

}

Results of the

请求发送成功!
执行其他任务...
正在使用data:请求参数.网络请求数据,耗时操作需要等待.
操作完毕,获取结果...
获取到结果...返回值aaaabb
  • The caller requests a resource, client.request("name");complete the preparation of the data, when to get the resource, data.getResult()if the resource is not ready isReady = false; it will block the thread. Resource acquisition until the thread is then awakened.

Guess you like

Origin www.cnblogs.com/haoworld/p/tb005bing-fa-bian-chengcallback-hefuture-mo-shi.html