In Java multithreaded programming, the common multithreaded design patterns include: Future mode, Master-worker mode, guarded suspeionsion mode, invariant mode and producer-consumer mode. This article focuses on the future model, with the following addresses for other multithreaded design patterns:
The addresses for other multithreaded design patterns are as follows:
A detailed description of the Master-worker model: A detailed explanation of master-worker patterns in Java multithreaded programming
Detailed explanation of guarded suspeionsion mode: Guarded suspeionsion mode in Java multithreaded programming
An explanation of invariant patterns: an explanation of invariant patterns in Java multithreaded programming
A detailed explanation of the producer-consumer model: producer-consumer model Java
1. The core idea of the future model
The core of the future model is the removal of the wait time for the main function and the time period that would otherwise have to wait for processing other business logic (according to Java Program Performance optimization).
The future mode is somewhat similar to a commodity order. When you shop online, after you submit your order, you don't have to wait at home at the time of receipt to do something else . When it comes to programming, when a request is submitted, it is expected to get a reply if the reply is likely to be slow. The traditional time waits until this reply receives the time to do other things, but if uses the future design pattern to wait for the reply arrival, waits for the reply the process to be possible to do other things.
For example, the following request calls the process sequence diagram. When a call request is made, it takes a long time to return. The diagram on the left needs to wait until the data is returned before other operations can be resumed, while the client on the right side of the future pattern does not have to wait for other things to do. When a server segment receives a request and returns the result to the client immediately, the result is not a real result (a virtual result), that is, a false data is obtained first, and then other operations are performed.
2. Future Mode Java implementation
The implementation of the client
The main functions that the client completes include: 1. Returns a futuredata;2. Opens a thread to construct the Realdata.
?
12345678910111213141516 |
public class Client {
public Data request(
final String string) {
final FutureData futureData =
new FutureData();
new Thread(
new Runnable() {
@Override
public void run() {
//RealData的构建很慢,所以放在单独的线程中运行
RealData realData =
new RealData(string);
futureData.setRealData(realData);
}
}).start();
return futureData;
//先直接返回FutureData
}
}
|
Implementation of data
This interface is implemented either Futuredata or Realdata.
?
123 |
public interface Data { String getResult() throws InterruptedException; } |
The realization of Futuredata
Futuredata is the key to the future mode, which is actually the proxy of the real data realdata, encapsulating the waiting process of acquiring realdata.
?
123456789101112131415161718192021 |
//FutureData是Future模式的关键,它实际上是真实数据RealData的代理,封装了获取RealData的等待过程
public class FutureData
implements Data {
RealData realData =
null
;
//FutureData是RealData的封装
boolean isReady =
false
;
//是否已经准备好
public synchronized void setRealData(RealData realData) {
if
(isReady)
return
;
this
.realData = realData;
isReady =
true
;
notifyAll();
//RealData已经被注入到FutureData中了,通知getResult()方法
}
@Override
public synchronized String getResult()
throws InterruptedException {
if
(!isReady) {
wait();
//一直等到RealData注入到FutureData中
}
return realData.getResult();
}
}
|
The realization of Realdata
Realdata is the final data that needs to be used, and its constructor is slow.
?
123456789101112131415161718 |
public class RealData
implements Data {
protected String data;
public RealData(String data) {
//利用sleep方法来表示RealData构造过程是非常缓慢的
try {
Thread.sleep(
1000
);
}
catch (InterruptedException e) {
e.printStackTrace();
}
this
.data = data;
}
@Override
public String getResult() {
return data;
}
}
|
Test run
The main function is primarily responsible for invoking the client initiating the request and using the returned data.
?
123456789101112 |
public class Application {
public static void main(String[] args)
throws InterruptedException {
Client client =
new Client();
//这里会立即返回,因为获取的是FutureData,而非RealData
Data data = client.request(
"name"
);
//这里可以用一个sleep代替对其他业务逻辑的处理
//在处理这些业务逻辑过程中,RealData也正在创建,从而充分了利用等待时间
Thread.sleep(
2000
);
//使用真实数据
System.out.println(
"数据="
+data.getResult());
}
}
|
3. JDK built-in implementation of the future model
Since the future is a very common multithreaded design pattern, the implementation of the future pattern is built into the JDK. These classes are inside the Java.util.concurrent package. The most important of these is the Futuretask class, which implements the Runnable interface, which runs as a separate thread. In its run () method, the callable interface is called through the sync internal class and the return object of the callable interface is maintained. When you use the Futuretask.get () method, the return object of the callable interface is returned. Similarly, for the above example, if you use the JDK's own implementation, you need to make the following adjustments.
First, the data interface and Futuredata are not needed, and the JDK has been implemented for us.
Second, Realdata changed to this:
?
1234567891011121314151617181920 |
import java.util.concurrent.Callable;
public class RealData
implements Callable<string> {
protected String data;
public RealData(String data) {
this
.data = data;
}
@Override
public String call()
throws Exception {
//利用sleep方法来表示真是业务是非常缓慢的
try {
Thread.sleep(
1000
);
}
catch (InterruptedException e) {
e.printStackTrace();
}
return data;
}
}</string>
|
Finally, when the test runs, this is called:
?
1234567891011121314151617181920 |
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Application {
public static void main(String[] args)
throws Exception {
FutureTask<string> futureTask =
new FutureTask<string>(
new RealData(
"name"
));
ExecutorService executor =
Executors.newFixedThreadPool(
1
);
//使用线程池
//执行FutureTask,相当于上例中的client.request("name")发送请求
executor.submit(futureTask);
//这里可以用一个sleep代替对其他业务逻辑的处理
//在处理这些业务逻辑过程中,RealData也正在创建,从而充分了利用等待时间
Thread.sleep(
2000
);
//使用真实数据
//如果call()没有执行完成依然会等待
System.out.println(
"数据=" + futureTask.get());
}
}</string></string>
|
The end of this article. Reprint please indicate the source.
Transfer from http://www.2cto.com/kf/201411/351903.html
The explanation of future mode in Java multithreaded programming < turn >