java 멀티스레드:future

4350 단어
우선future는 하나의 인터페이스입니다. 이 인터페이스는 라인이 다른 단계로 되돌아오는 결과를 수신하는 데 사용됩니다.다중 루틴에 익숙한 사람들은 Executor 서비스에서 다음 두 가지 방법으로 임무를 제출할 수 있다는 것을 알아야 한다.
 Future submit(Callable task);
void execute(Runnable command);

callable과runnable의 차이는 많지 않다.그러나runnable는 결과를 되돌려주지 않고 되돌려주는 이상을 던질 수 없습니다.따라서callable 기능은 더욱 강력합니다. 라인이 실행되면 값을 되돌려줍니다.이 값은Future에 의해 얻을 수 있다. 즉, Future는 라인이 비동기적으로 실행되는 결과를 얻을 수 있다.이 중점은 비동기적이다. 즉, 우리는 라인의 실행 결과를 기다릴 때 다른 일을 할 수 있다는 것이다.
Futrue는 목표 라인이 콜을 호출하는 상황을 감시할 수 있습니다. Future의 get () 방법을 호출해서 결과를 얻을 때 현재 라인이 막히기 시작하고, 직접 콜 방법이 결과를 되돌려줍니다.
Future는 비동기 계산의 결과를 나타낸다. 이 클래스에는 다음과 같은 방법이 있다.
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit);

위의 방법에서 보듯이 퓨처의 감청 상태는 취소할 수 있다.비동기 결과를 기다리는 것을 막을 때도 시간 초과를 설정할 수 있습니다.
Future 구현 클래스: FutureTask FutureTask는 두 개의 인터페이스를 구현했는데 그것이 바로 Runnable과Future입니다.그래서 이 클래스는executor에 임무로 제출할 수도 있고, 라인이 다른 방식으로 실행된 결과를 수신할 수도 있습니다.이런 조합은 어느 정도 일리가 있는데 여기에는Future 모델과 관련된다.우리가 간단하게 소개하자면, 만약 우리가 매우 많은 시간을 소모하는 반환값을 필요로 한다면, 이 반환값은 즉각 필요로 하는 것이 아니다.우리는 다른 라인으로 되돌아오는 값을 계산할 수 있다. 현재 라인은 이 되돌아오는 값을 사용하기 전에 다른 조작을 할 수 있다. 이 되돌아오는 값이 필요할 때Future를 통해 얻을 수 있다.
public class FutureTest {    
    public static void main(String[] args) {   
  
        //ExecutorService.submit()  
        ExecutorService threadPool = Executors.newSingleThreadExecutor();    
        Future future = threadPool.submit(new Callable() {    
            public Integer call() throws Exception {    
                return new Random().nextInt(100);    
            }    
        });   
  
        try {    
            Thread.sleep(5000);//            
  
            int result = future.get()); //Future.get()  
  
        } catch (InterruptedException e) {    
            e.printStackTrace();    
        } catch (ExecutionException e) {    
            e.printStackTrace();    
        }    
    }    
}  

반환 값이 있는 여러 작업을 수행하고 반환 값이 여러 개 있는 경우 CompletionService를 사용할 수 있습니다.

public class CompletionServiceDemo {

    public static class Task implements Callable {
        private int i;

        Task(int i) {
            this.i = i;
        }

        @Override
        public Integer call() throws Exception {
            Thread.sleep(new Random().nextInt(5000));
            System.out.println(Thread.currentThread().getName() + "   " + i);
            return i;
        }
    }

    public void run() {
        ExecutorService pool = Executors.newFixedThreadPool(10);
        CompletionService completionServcie = new ExecutorCompletionService(
                pool);
        try {
            for (int i = 0; i < 10; i++) {
                completionServcie.submit(new CompletionServiceDemo.Task(i));
            }
            for (int i = 0; i < 10; i++) {
                // take              Future   。
                // poll    ,         Future   ,     null。
                System.out.println(completionServcie.take().get());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
            pool.shutdown();
        }
    }

    public static void main(String[] args) {
        new CompletionServiceDemo().run();
    }
}

이를 통해 알 수 있듯이 Completion 서비스는 여러 개의 반환 값을 가진 작업을 제출할 수 있다. Completion 서비스는 Executor와 BlockingQueue에 해당한다. 장면을 이용하여 하위 라인에서 일련의 작업을 병발한 후에 메인 라인은 하위 라인 작업의 반환 값을 실시간으로 되찾고 이 반환 값을 동시에 순서대로 처리해야 한다. 먼저 되돌아오는 사람이 먼저 누구를 처리해야 한다.
Completion Service를 사용하지 않으면, 우리는 모든 작업의 되돌아오는 값을 저장하기 위해Future의 집합을 만들 수 있습니다.그러나 우리가 두루 모은 집합에는 순서가 있기 때문에 임무가 이 순서에 따라 집행될 것이라고 보장할 수 없다.뒤의 모든 임무를 이미 완수했을 수도 있고, 첫 번째만 완수하지 못했을 수도 있다.이것은 get 방법을 호출하는 것입니다. 여전히 막힐 것입니다.만약 시스템이 모든 라인이 완성된 후에 그 결과에 따라 뒷일을 계속할 수 있도록 설계된다면 리스트 뒤에 있지만 먼저 완성된 라인에 대해서는 추가 대기 시간이 증가할 것이다.Completion 서비스의 실현은Future 대상을 저장하는 BlockingQueue를 유지하는 것이다.이 Future 대상의 상태가 끝날 때만 이 Queue에 가입할 수 있습니다. take () 방법은 사실 Producer-Consumer의 Consumer입니다.이것은 Queue에서 Future 대상을 꺼냅니다. 만약 Queue가 비어 있다면 완성된 Future 대상이 Queue에 추가될 때까지 막힙니다.

좋은 웹페이지 즐겨찾기