>  기사  >  Java  >  Java가 future를 사용하여 적시에 멀티 스레드 실행 결과를 얻는 방법에 대한 분석 예

Java가 future를 사용하여 적시에 멀티 스레드 실행 결과를 얻는 방법에 대한 분석 예

黄舟
黄舟원래의
2017-10-12 10:20:512754검색

Java 프로그래밍에서는 스레드의 실행 결과를 적시에 얻어야 하는 경우가 있습니다. 이 기사에서는 future를 사용하여 Java에서 스레드의 실행 결과를 적시에 얻는 방법을 소개합니다. 그것을 참조하십시오.

Future 인터페이스는 java.util.concurrent 패키지에 있는 Java 표준 API의 일부입니다. Future 인터페이스는 Java 스레드 Future 모드의 구현이며 비동기 계산에 사용할 수 있습니다.

Future를 사용하면 3단계 프로그래밍을 수행할 수 있습니다. 1. 멀티 스레드 작업 시작 2. 기타 작업 처리 3. 멀티 스레드 작업 결과 수집. 이는 비차단 작업 호출을 달성합니다. 도중에 문제가 발생했습니다. 즉, 결과를 비동기적으로 얻을 수 있지만 Future의 결과를 isdone을 통해 판단하여 결과가 있는지 확인해야 하거나, get() 함수를 사용하여 결과를 얻을 수 있다는 것입니다. 실행 결과가 차단됩니다. 이 방법으로 다른 스레드의 결과 상태를 실시간으로 추적할 수 없으므로 get을 직접 사용할 때는 주의해서 사용해야 하며 isdone과 함께 사용하는 것이 가장 좋습니다.

적시에 스레드의 결과를 얻는 더 좋은 방법은 다음과 같습니다. 내부적으로 차단 대기열을 추가하여 향후 값을 얻은 다음 반환 값에 따라 작업을 수행하는 CompletionService를 사용하는 것입니다. 일반적인 future 사용과 CompletionService 사용에 대한 두 가지 테스트 사례는 다음과 같습니다.


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

실행 결과는 future가 목록에 포함될 때와 동일한 순서인 0, 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

다음은 첫 번째입니다. 실행이 완료된 스레드가 먼저 처리되도록 하는 솔루션:


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

먼저 종료되는 스레드의 결과가 먼저 처리됩니다.


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

요약

위 내용은 Java가 future를 사용하여 적시에 멀티 스레드 실행 결과를 얻는 방법에 대한 분석 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.