Heim  >  Artikel  >  Java  >  Beispielanalyse, wie Java Future nutzt, um zeitnah Multithread-Laufergebnisse zu erhalten

Beispielanalyse, wie Java Future nutzt, um zeitnah Multithread-Laufergebnisse zu erhalten

黄舟
黄舟Original
2017-10-12 10:20:512716Durchsuche

Bei der Java-Programmierung ist es manchmal notwendig, die laufenden Ergebnisse von Threads rechtzeitig abzurufen. In diesem Artikel erfahren Sie anhand eines relevanten Beispiels, wie Java die Zukunft nutzt, um die laufenden Ergebnisse von Threads rechtzeitig abzurufen beziehen Sie sich darauf.

Die Future-Schnittstelle ist Teil der Java-Standard-API und befindet sich im Paket java.util.concurrent. Die Future-Schnittstelle ist eine Implementierung des Java-Thread-Future-Modus und kann für asynchrone Berechnungen verwendet werden.

Mit Future können Sie eine dreistufige Programmierung durchführen: 1. Multithread-Aufgaben starten 2. Andere Dinge verarbeiten 3. Multithread-Aufgabenergebnisse sammeln. Dadurch wird ein nicht blockierender Aufgabenaufruf erreicht. Unterwegs bin ich auf ein Problem gestoßen, das heißt, obwohl das Ergebnis asynchron abgerufen werden kann, muss das Ergebnis der Zukunft über isdone beurteilt werden, um festzustellen, ob ein Ergebnis vorliegt, oder die Funktion get () kann verwendet werden, um das zu erhalten Ausführungsergebnis in blockierender Weise. Auf diese Weise kann der Ergebnisstatus anderer Threads nicht in Echtzeit verfolgt werden. Daher sollten Sie bei der direkten Verwendung von get Vorsicht walten lassen. Am besten verwenden Sie es in Verbindung mit isdone.

Hier ist eine bessere Möglichkeit, die Ergebnisse eines Threads zeitnah zu erhalten: Verwenden Sie CompletionService, der intern eine Blockierungswarteschlange hinzufügt, um den Wert in der Zukunft abzurufen, und führen Sie dann basierend darauf eine entsprechende Verarbeitung durch der Rückgabewert. Die beiden Testfälle für die allgemeine zukünftige Verwendung und die Verwendung von CompletionService lauten wie folgt:


import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
 * 多线程执行,异步获取结果
 * 
 * @author i-clarechen
 *
 */
public class AsyncThread {
  public static void main(String[] args) {
    AsyncThread t = new AsyncThread();
    List<Future<String>> futureList = new ArrayList<Future<String>>();
    t.generate(3, futureList);
    t.doOtherThings();
    t.getResult(futureList);
  }
  /**
   * 生成指定数量的线程,都放入future数组
   * 
   * @param threadNum
   * @param fList
   */
  public void generate(int threadNum, List<Future<String>> fList) {
    ExecutorService service = Executors.newFixedThreadPool(threadNum);
    for (int i = 0; i < threadNum; i++) {
      Future<String> f = service.submit(getJob(i));
      fList.add(f);
    }
    service.shutdown();
  }
  /**
   * other things
   */
  public void doOtherThings() {
    try {
      for (int i = 0; i < 3; i++) {
        System.out.println("do thing no:" + i);
        Thread.sleep(1000 * (new Random().nextInt(10)));
      }
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  /**
   * 从future中获取线程结果,打印结果
   * 
   * @param fList
   */
  public void getResult(List<Future<String>> fList) {
    ExecutorService service = Executors.newSingleThreadExecutor();
    service.execute(getCollectJob(fList));
    service.shutdown();
  }
  /**
   * 生成指定序号的线程对象
   * 
   * @param i
   * @return
   */
  public Callable<String> getJob(final int i) {
    final int time = new Random().nextInt(10);
    return new Callable<String>() {
      @Override
      public String call() throws Exception {
        Thread.sleep(1000 * time);
        return "thread-" + i;
      }
    };
  }
  /**
   * 生成结果收集线程对象
   * 
   * @param fList
   * @return
   */
  public Runnable getCollectJob(final List<Future<String>> fList) {
    return new Runnable() {
      public void run() {
        for (Future<String> future : fList) {
          try {
            while (true) {
              if (future.isDone() && !future.isCancelled()) {
                System.out.println("Future:" + future
                    + ",Result:" + future.get());
                break;
              } else {
                Thread.sleep(1000);
              }
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    };
  }
}

Das Drucken der laufenden Ergebnisse erfolgt in derselben Reihenfolge wie in der Zukunft in die Liste einfügen, die 0 ist. 1, 2:


do thing no:0
do thing no:1
do thing no:2
Future:java.util.concurrent.FutureTask@68e1ca74,Result:thread-0
Future:java.util.concurrent.FutureTask@3fb2bb77,Result:thread-1
Future:java.util.concurrent.FutureTask@6f31a24c,Result:thread-2

Das Folgende ist die Lösung für den Thread, dessen Ausführung zuerst abgeschlossen ist:


import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
public class testCallable {
  public static void main(String[] args) {
    try {
      completionServiceCount();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    }
  }
  /**
   * 使用completionService收集callable结果
   * @throws ExecutionException 
   * @throws InterruptedException 
   */
  public static void completionServiceCount() throws InterruptedException, ExecutionException {
    ExecutorService executorService = Executors.newCachedThreadPool();
    CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(
        executorService);
    int threadNum = 5;
    for (int i = 0; i < threadNum; i++) {
      completionService.submit(getTask(i));
    }
    int sum = 0;
    int temp = 0;
    for(int i=0;i<threadNum;i++){
      temp = completionService.take().get();
      sum += temp;
      System.out.print(temp + "\t");
    }
    System.out.println("CompletionService all is : " + sum);
    executorService.shutdown();
  }
  public static Callable<Integer> getTask(final int no) {
    final Random rand = new Random();
    Callable<Integer> task = new Callable<Integer>() {
      @Override
      public Integer call() throws Exception {
        int time = rand.nextInt(100)*100;
        System.out.println("thead:"+no+" time is:"+time);
        Thread.sleep(time);
        return no;
      }
    };
    return task;
  }
}

Das laufende Ergebnis ist das Ergebnis des Threads, der zuerst endet und zuerst verarbeitet wird:


thead:0 time is:4200
thead:1 time is:6900
thead:2 time is:2900
thead:3 time is:9000
thead:4 time is:7100
  0  1  4  3  CompletionService all is : 10

Zusammenfassung

Das obige ist der detaillierte Inhalt vonBeispielanalyse, wie Java Future nutzt, um zeitnah Multithread-Laufergebnisse zu erhalten. 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