Heim  >  Artikel  >  Java  >  Detaillierte Erklärung des Future-Musters in Java

Detaillierte Erklärung des Future-Musters in Java

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

Der folgende Editor bringt Ihnen ein Klischee über den Future-Modus in Java. Der Herausgeber findet es ziemlich gut, deshalb teile ich es jetzt mit Ihnen und gebe es als Referenz. Kommen Sie und werfen Sie einen Blick mit dem Editor

jdk1.7.0_79

Dieser Artikel ist eigentlich eine Fortsetzung oder Ergänzung des oben genannten „Besprechen Sie kurz die Submit-Methode des ThreadPoolExecutor-Thread-Pools“. FutureTask erschien in der oben erwähnten Submit-Methode, was mich dazu zwang, anzuhalten und in den Future-Modus von Java zu wechseln.

Zukunft ist ein Entwurfsmuster in der gleichzeitigen Programmierung. Für Multithreading muss Thread A auf das Ergebnis von Thread B warten. Er muss nicht ständig auf B warten. Es kann eine erste Zukunft erhalten, die Zukunft wird das tatsächliche Ergebnis erhalten, nachdem B das Ergebnis hat.

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

Mit anderen Worten, Future stellt das Ergebnis einer asynchronen Berechnung dar.

Das Obige stellt das Ausführungsprinzip des Zukunftsmodus dar. Gemäß Online-Beispielen können wir selbst einen Zukunftsmodus implementieren.

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());
 }
}

Lesen Sie die Implementierung des Zukunftsmodus im obigen Programm sorgfältig durch. Es ist nicht schwer herauszufinden, dass der Zukunftsmodus eine Kombination aus asynchronen Anforderungen und Proxy-Modus . Natürlich wurde der Future-Modus für uns im JDK implementiert.

Ändern Sie die RealData-Klasse:

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;
 }
}
Ändern Sie die Haupttestklasse:

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());
 }
}
Kehren Sie nun zum AbstractExecutorService zurück, der nicht vorhanden war noch gelöst. #submit-Methode.

Analog zur obigen Client#request-Methode wird zunächst in Client#request eine FutureData-Instanz und in AbstractExecutorService#submit eine FutureTask-Instanz erstellt. Anschließend erstellt Client#request einen neuen Thread für die asynchrone Ausführung. Aufgabe und geben Sie FutureData direkt zurück. In AbstractExecutorService#submit wird die Aufgabe auch an die Ausführungsmethode übergeben und gibt FutureTask direkt zurück. Natürlich ist die Implementierung des Future-Modus im JDK komplizierter.

In „

ThreadPoolExecutor-Thread-Pool-Prinzip und seine Ausführungsmethode “ haben wir die Ausführungsmethode 1145 der ThreadPoolExecutor$Worker#runWorker-Methode erklärt:

//ThreadPoolExecutor$Worker#runWorker
task.run();
Submit-Aufrufe ausführen, um die Ausführungsmethode auszuführen. Was tatsächlich ausgeführt wird, ist die Ausführungsmethode in FutureTask. In FutureTask#run können Sie die asynchrone Ausführung von Aufgaben vom Typ Callable und das Speichern der Ergebnisse sehen.

Das obige ist der detaillierte Inhalt vonDetaillierte Erklärung des Future-Musters in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn