Home  >  Article  >  Java  >  Detailed explanation of Future pattern in java

Detailed explanation of Future pattern in java

怪我咯
怪我咯Original
2017-06-30 10:42:113595browse

The following editor will bring you a cliché about the Future mode in Java. The editor thinks it’s pretty good, so I’ll share it with you now and give it as a reference. Let’s follow the editor and take a look.

##jdk1.7.0_79

This article is actually a continuation or supplement to the above "

Briefly talk about the submit method of ThreadPoolExecutor thread pool". FutureTask appeared in the submit method mentioned above, which forced me to stop and turn to Java's Future mode.

Future is a

design pattern in concurrent programming. For multi-threading, thread A needs to wait for the result of thread B. It does not need to wait for B all the time. It can get one first. Future Future will get the real result after B has the result.

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(callable); //主线程需要callable线程的结果,先拿到一个未来的Future
System.out.println(future.get()); //有了结果后再根据get方法取真实的结果,当然如果此时callable线程如果没有执行完get方法会阻塞执行完,如果执行完则直接返回结果或抛出异常

In other words, Future represents the result of an asynchronous calculation.

The above represents the execution principle of Future mode. According to online examples, we can implement a Future mode ourselves.

package com.future;

/**
 * 数据结果
 * Created by yulinfeng on 6/18/17.
 */
public interface Data {
 String getResult() throws InterruptedException;
}
package com.future;

/**
 * 结果的真实计算过程
 * Created by yulinfeng on 6/18/17.
 */
public class RealData implements Data {
 protected String data;

 public RealData(String data) {
  try {
   System.out.println("正在计算结果");
   Thread.sleep(3000);  //模拟计算
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  this.data = data + “ world”;
 }

 public String getResult() throws InterruptedException {
  return data;
 }
}
package com.future;

/**
 * 真实结果RealData的代理
 * Created by yulinfeng on 6/18/17.
 */
public class FutureData implements Data {
 RealData realData = null; //对RealData的封装,代理了RealData
 boolean isReady = false; //真实结果是否已经准备好

 public synchronized void setResultData(RealData realData) {
  if (isReady) {
   return;
  }
  this.realData = realData;
  isReady = true;
  notifyAll(); //realData已经被注入到了futureData中,通知getResult方法
 }

 public synchronized String getResult() throws InterruptedException {
  if (!isReady) {
   wait();  //数据还未计算好,阻塞等待
  }
  return realData.getResult();
 }
}
package com.future;

/**
 * Client主要完成的功能包括:1. 返回一个FutureData;2.开启一个线程用于构造RealData
 * Created by yulinfeng on 6/18/17.
 */
public class Client {

 public Data request(final String string) {
  final FutureData futureData = new FutureData();

  /*计算过程比较慢,单独放到一个线程中去*/
  new Thread(new Runnable() {

   public void run() {
    RealData realData = new RealData(string);
    futureData.setResultData(realData);
   }
  }).start();

  return futureData; //先返回一个“假”的futureData
 }
}
/**
 * 负责调用Client发起请求,并使用返回的数据。
 * Created by yulinfeng on 6/18/17.
 */
public class Main {
 public static void main(String[] args) throws InterruptedException {
  Client client = new Client();
  System.out.println("准备计算结果");
  Data data = client.request("hello"); //立即返回一个“假”的futureData,可以不用阻塞的等待数据返回,转而执行其它任务
  System.out.println("执行其它任务");
  Thread.sleep(3000);  //模拟执行其它任务
  System.out.println("数据的计算结果为:" + data.getResult());
 }
}

After carefully reading the implementation of Future mode in the above program, it is not difficult to find that Future mode is a combination of asynchronous requests and

Proxy mode. Of course, the Future mode has been implemented for us in the JDK.

Modify the RealData class:

package com.future;

import java.util.concurrent.Callable;

/**
 * 结果的真实计算过程
 * Created by yulinfeng on 6/18/17.
 */
public class RealData2 implements Callable<String> {
 protected String data;

 public RealData2(String data) {
  this.data = data;
 }
 public String call() throws Exception {
  try {
   System.out.println("正在计算结果");
   Thread.sleep(2000);  //模拟计算结果
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  this.data = data + " world";
  return data;
 }
}

Modify the Main test class:

package com.future;

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

/**
 * 负责调用Executor的submit,并使用返回的数据。
 * Created by yulinfeng on 6/18/17.
 */
public class Main2 {

 public static void main(String[] args) throws InterruptedException, ExecutionException {
  ExecutorService client = Executors.newSingleThreadExecutor(); //类似Client
  System.out.println("准备计算结果");
  Future<String> data = client.submit(new RealData2("hello")); //类似Client.request
  System.out.println("执行其它任务");
  Thread.sleep(3000);
  System.out.println("数据的计算结果为:" + data.get());
 }
}

Now return to the AbstractExecutorService#submit method that has not been solved above.

Analogous to the Client#request method above, a FutureData instance is first created in Client#request, and a FutureTask instance is created in AbstractExecutorService#submit, and then Client#request creates a new thread for asynchronous execution. task and directly returns FutureData. In AbstractExecutorService#submit, the task is also handed over to the execute method and directly returns FutureTask. Of course, the implementation of Future mode in JDK is more complicated.

In "

ThreadPoolExecutor thread pool principle and its execute method" we explained the execute method. Line 1145 of the ThreadPoolExecutor$Worker#runWorker method is the call to the task task:

//ThreadPoolExecutor$Worker#runWorker
task.run();

submit calls execute to execute the run method. What is actually executed is the run method in FutureTask. In FutureTask#run, you can see the asynchronous execution of tasks of the Callable type and the saving of the results.

The above is the detailed content of Detailed explanation of Future pattern in java. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn