Futrue模式Demo:
public class FutureData<T> {
private boolean mIsReady = false;
private T mData;
public synchronized void setData(T data) {
mIsReady = true;
mData = data;
notifyAll();
}
public synchronized T getData() {
while (!mIsReady) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return mData;
}
}
public class Server {
public FutureData<String> getString() {
final FutureData<String> data = new FutureData<>();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
data.setData("world");
}
}).start();
return data;
}
}
public class Test{
public static void main(String[] args) {
Server server = new Server();
FutureData<String> futureData = server.getString();
//先执行其他操作
String hello = "hello";
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print(hello + " " + futureData.getData());
System.out.print("阻塞啦!");
}
}
代码解释:
Future模式就是另起线程执行任务,只不过,将执行的返回值,存入了FutureData类中,可以在主线程中调用FutureData中的get方法进行查看。
个人理解:
futureData.getData()
执行之前,主线程与子线程是异步非阻塞执行的。
futureData.getData()
执行开始,主线程与子线程是异步阻塞执行的。阻塞
体现在主线程会等待线程执行完才结束,这是
while (!mIsReady) {
try {
wait();
}
}
起到的作用。因此,私以为,Future模式完全可以用以下两个个步骤进行替代:
step1:起子线程执行任务,返回结果通过static静态变量提供给主线程
step2:主线程中加入join,等待子线程完成,并最终从static静态变量获取子线程的返回值。
该Future模式的demo示例很好地模拟了java.util.concurrent.Future
的原理。另有一个demo可以很好的描述Future模式的原理:
public class Test{
public static void main(String[] args) {
Future<String> future = Executors.newSingleThreadExecutor()
.submit(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(2000);
return "Hello djg";
}
});
try {
System.out.print(future.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("hello, cj");
}
}
代码中,hello,cj
必然是在hello,djg
之后打印出来,可见,Future模式在获取返回值的时候,确实会阻塞主线程!
参考:
https://www.jianshu.com/p/949d44f3d9e3
https://www.jianshu.com/p/6b504bb08aaa