Callable
In the Java
middle, there are two ways to create threads, one is inherited Thread
categories, one is to realize Runnable
the 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, Java
in also provides for the use Callable
and Future
operations to achieve access to the results of the task. Callable
To perform the task, produce results, and Future
to get results.
Callable
Interface and Runnable
whether an interface similar to the view source code, we can see Callable
the 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 Runnable
the interface except that, call
the method having the generic return value V .
Future
Common 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 returnsfalse
; - 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 returntrue
; when the task has been launched , the implementation ofcancel(false)
the method will have no effect on the task executing thread (thread to perform normal to complete), then returnsfalse
; - When the task has been completed, the implementation
cancel(...)
method returnsfalse
.mayInterruptRunning
Parameter indicates whether to interrupt the execution threads.
- If the task has not started, execute
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
Future
The 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
Futrure
mode: For multithreaded, if thread A thread to wait for B
the result, then the thread A
is no need to wait B
until B
there result, you can get a future Future
, and so B
the 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.
 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 Client
a FutureSubject
to meet the needs of the client, the same time it, Future
will pass another Thread
after to construct a real resource, resources ready, giving future
a 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 readyisReady = false
; it will block the thread. Resource acquisition until the thread is then awakened.