JAVA Future 류 의 사용 에 대한 상세 한 설명

11312 단어 JAVAFuture종류
머리말
고성능 프로 그래 밍 에서 동시 프로 그래 밍 은 이미 매우 중요 한 부분 이 되 었 다.단일 핵 CPU 의 성능 이 한계 에 이 르 렀 을 때 우 리 는 다 핵 을 통 해 시스템 의 성능 을 한층 더 향상 시 킬 수 밖 에 없 기 때문에 병행 프로 그래 밍 을 탄생 시 켰 다.
직렬 프로 그래 밍 보다 동시 프로 그래 밍 이 더 어렵 고 실수 하기 쉬 우 므 로 우 리 는 선인 들 의 우수한 성숙 한 디자인 모델 을 참고 하여 우리 의 디자인 을 더욱 건장 하고 완벽 하 게 해 야 한다.
한편,Future 모델 은 바로 그 중에서 가장 광범 위 하 게 사용 되 고 매우 중요 한 디자인 모델 이다.오늘 은 병 이와 퓨 처 모드 를 알 아 보 겠 습 니 다!
생활 속 의 Future 모델
퓨 처 모델 을 더 빨리 이해 하기 위해 서 는 삶 의 예 를 살 펴 보 자.
필드 1:
점심 시간 이 되 었 습 니 다.학생 들 은 밥 을 먹 으 러 가 야 합 니 다.왕 군 은 계단 을 내 려 가 20 분 걸 었 습 니 다.KFC 에 왔 습 니 다.주문 하고 줄 을 서 며 밥 을 먹 는 데 모두 20 분 이 걸 렸 습 니 다.그리고 20 분 걸 려 서 회사 로 돌아 가 계속 일 했 습 니 다.모두 1 시간 입 니 다.
장면 2
점심 시간 이 되자 친구 들 이 밥 을 먹 으 러 가 려 고 합 니 다.왕 군 은 KFC 에 게 배달 을 시 켰 습 니 다.곧 주문 서 를 받 았 습 니 다.(주문 서 는 밥 으로 먹 을 수 없 지만 주문 이 있어 서 밥 을 못 먹 을 까 봐 걱정 입 니 다)이 어 왕 군 은 계속 일 을 할 수 있 었 고 30 분 후에 배달 이 도 착 했 습 니 다.이 어 왕 군 은 10 분 동안 밥 을 먹 었 습 니 다.이 어 계속 일 을 할 수 있 게 되 었 고 옆집 왕 군 에 게 성공 적 으로 말 렸 습 니 다.

분명히 이 두 장면 에서 왕 군 은 근무 시간 이 더욱 빡빡 하 다.특히 줄 을 서 는 시간 은 배달 원 에 게 맡 길 수 있 기 때문에 자신의 본업 에 더욱 집중 할 수 있다.똑똑 한 당신 도 이미 깨 달 았 을 것 입 니 다.장면 1 은 전형 적 인 함수 동기 호출 이 고 장면 2 는 전형 적 인 비동기 호출 입 니 다.
한편,장면 2 의 비동기 호출 은 또 하나의 특징 이 있 는데 그것 이 반환 값 을 가지 고 있다 는 것 이다.이 반환 값 은 바로 우리 의 주문 이다.이 주문 서 는 매우 중요 하 다.이 주문 서 를 통 해 우 리 는 현재 이 호출 에 대응 하 는 결 과 를 얻 을 수 있다.
이곳 의 주문 은 Future 모델 의 Future 와 같 습 니 다.이것 은 계약 이 고 약속 입 니 다.주문 서 는 먹 을 수 없 지만 주문 서 를 손 에 쥐 고 먹 을 것 이 없 는 것 을 두려워 하지 않 습 니 다.퓨 처 는 우리 가 원 하 는 결과 가 아니 지만 퓨 처 를 들 고 미래 에 우리 가 원 하 는 결 과 를 얻 을 수 있 습 니 다.
따라서 Future 모드 는 반환 값 이 필요 한 비동기 호출 을 잘 해결 했다.
Future 모드 의 주요 역할
하나의 전형 적 인 Future 모델 은 다음 과 같은 몇 가지 부분 으로 구성 된다.
  • Main:시스템 시작,클 라 이언 트 호출 요청
  • Client:데이터 대상 을 되 돌려 주 고 FutureData 를 즉시 되 돌려 주 며 Client Thread 스 레 드 조립 RealData
  • 를 엽 니 다.
  • Data:데 이 터 를 되 돌려 주 는 인터페이스
  • Future Data:Future 데 이 터 는 구조 가 빠 르 지만 가상 데이터 로 RealData 를 설치 해 야 합 니 다.예 를 들 어 주문
  • 과 같 습 니 다.
  • RealData:실제 데이터 의 구 조 는 비교적 느 리 고 위의 사례 에서 KFC 점심 과 같다.
  • 그들 간 의 상호 관 계 는 다음 과 같다.

    이 가운데 주목 할 점 은 데이터,리 얼 데이터,퓨 처 데이터 다.이것 은 전형 적 인 대리 모델 로 Data 인 터 페 이 스 는 대외 데 이 터 를 나타 내 고 RealData 는 진실 한 데 이 터 를 나타 내 는 것 이 점심 과 같 아서 그 원 가 를 얻 는 데 많은 시간 이 필요 하 다.상대 적 인 FutureData 는 RealData 의 대리 로 서 하나의 주문/계약 과 유사 하 며 FutureData 를 통 해 장래에 RealData 를 얻 을 수 있다.
    따라서 Future 모델 은 본질 적 으로 대리 모델 의 실제 응용 이다.
    간단 한 Future 모드 구현
    위의 디자인 에 따라 간단 한 대리 모델 을 실현 합 시다!
    먼저 Data 인터페이스 로 데 이 터 를 대표 합 니 다.
    
    public interface Data {
        public String getResult ();
    }
    
    
    이 어 Future Data 이자 전체 Future 모델 의 핵심 이다.
    
    public class FutureData implements Data {
        //       RealData
        protected RealData realdata = null;          
        protected boolean isReady = false;
        public synchronized void setRealData(RealData realdata) {
            if (isReady) { 
                return;
            }
            this.realdata = realdata;
            isReady = true;
            //RealData     ,  getResult()
            notifyAll();                            			
        }
        //   RealData    
        public synchronized String getResult() {        	
            while (!isReady) {
                try {
                    //    ,  RealData   
                    wait();                        			
                } catch (InterruptedException e) {
                }
            }
            //        RealData  
            return realdata.result;                    		
        }
    }
    
    
    다음은 RealData:
    
    public class RealData implements Data {
        protected final String result;
        public RealData(String para) {
            StringBuffer sb=new StringBuffer();
            //        ,  RealData        
            result =sb.toString();
        }
        public String getResult() {
            return result;
        }
    }
    
    
    그리고 Client 에서 Data 를 받 습 니 다:
    
    public class Client {
        //        ,   Data     Future
        public Data request(final String queryStr) {
            final FutureData future = new FutureData();
            new Thread() {                                      
                public void run() {                    	
                    // RealData     ,           
                    RealData realdata = new RealData(queryStr);
                    //setRealData()    notify()     future    
                    future.setRealData(realdata);
                }                                               
            }.start();
            // FutureData      ,    RealData    
            return future;                        		
        }
    }
    
    
    마지막 메 인 함수,모든 것 을 연결 합 니 다:
    
    public static void main(String[] args) {
        Client client = new Client();
        //       ,      FutureData   RealData
        Data data = client.request("name");
        System.out.println("    ");
        try {
            //       sleep             
            //             ,RealData   ,           
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        //       ,             ,getResult()        ,   
        System.out.println("   = " + data.getResult());
    }
    
    
    이것 은 가장 간단 한 Future 모델 의 실현 으로 간단 하지만 Future 모델 에서 가장 정수 적 인 부분 을 포함 했다.JDK 내부 의 퓨 처 대상 을 이해 하 는 데 중요 한 역할 을 한다.
    자바 의 Future 모드
    퓨 처 모델 은 이렇게 자주 사용 되 는데 JDK 내부 에서 비교적 전면적 인 실현 과 지 지 를 얻 었 다.다음은 JDK 내부 의 퓨 처 실현 을 살 펴 보 자.

    먼저,JDK 내부 에 Future 인터페이스 가 있 는데 이것 이 바로 앞에서 언급 한 주문 과 비슷 합 니 다.물론 완전한 상업 화 제품 으로서 이곳 의 Future 기능 이 더욱 풍부 해 졌 습 니 다.get()방법 으로 실제 데 이 터 를 얻 는 것 을 제외 하고 보조 적 인 방법 도 제공 합 니 다.예 를 들 어:
  • cancel():너무 오래 기다 리 면 이 미 션 을 취소 할 수 있 습 니 다
  • isCanceled():미 션 취소 한 거 아니 야
  • isDone():임 무 를 완 수 했 나 요
  • get():2 개의 get()방법 이 있 습 니 다.인자 가 없 는 것 은 무한 한 기다 림 을 표시 하거나 주어진 시간 만 기다 릴 수 있 습 니 다.
  • 다음 코드 는 이 Future 의 사용 방법 을 보 여 줍 니 다.
    
            //             
            ExecutorService executor = Executors.newFixedThreadPool(1);
            //  FutureTask,        client.request("name")     
            //         RealData call()  
            Future<String> future = executor.submit(new RealData("name"));
            System.out.println("    ,     ");
            try {
                //              ,    sleep           
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
            //    call()        ,      
            System.out.println("   = " + future.get());
    
    전체 사용 과정 은 매우 간단 합 니 다.다음은 executor.submit()에서 무슨 일이 일 어 났 는 지 분석 해 보 겠 습 니 다.
    
        public <T> Future<T> submit(Callable<T> task) {
            if (task == null) throw new NullPointerException();
            //   Callable  ,    RunnableFuture,      FutureTask
            RunnableFuture<T> ftask = newTaskFor(task);
            // ftask      
            //        ,  run()  ,          
            execute(ftask);
            //    Future,      Future          
            return ftask;
        }
        protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
            return new FutureTask<T>(callable);
        }
    
    가장 중요 한 부분 은 아래 에 있 습 니 다.Future Task 가 하나의 스 레 드 로 단독 실 행 될 때 결 과 를 outcome 에 저장 하고 작업 의 상 태 를 설정 합 니 다.다음은 Future Task 의 run()방법 입 니 다.

    Future Task 에서 얻 은 결 과 는 다음 과 같 습 니 다.
    
        public V get() throws InterruptedException, ExecutionException {
            int s = state;
            //      ,   ,   park()      
            //  ,        FutureTask waiters       
            if (s <= COMPLETING)
                s = awaitDone(false, 0L);
            return report(s);
        }
        private V report(int s) throws ExecutionException {
            //outcome             
            Object x = outcome;
            if (s == NORMAL)
                //    ,   outcome
                return (V)x;
            //        ,         ,      ,     
            if (s >= CANCELLED)
                throw new CancellationException();
            throw new ExecutionException((Throwable)x);
        }
    
    Future 모드 의 고급 버 전―Complete bleFuture
    Future 모드 가 좋 지만 문제 가 있 습 니 다.바로 작업 을 스 레 드 에 제출 한 후에 스 레 드 를 호출 하면 이 작업 이 언제 실 행 될 지 모 릅 니 다.get()방법 이나 isDone()방법 으로 판단 하면 불필요 한 기다 림 이 있 을 수 있 습 니 다.그러면 시스템 의 스루풋 을 높이 기 어렵 습 니 다.
    이 문 제 를 해결 하기 위해 JDK 는 Future 모델 을 강화 하고 Complete Future 를 만 들 었 습 니 다.Future 모델 의 업그레이드 버 전 으로 이해 할 수 있 습 니 다.가장 큰 역할 은 리 셋 체 제 를 제공 하 는 것 입 니 다.작업 이 완 료 된 후에 후속 처 리 를 자동 으로 리 셋 할 수 있 습 니 다.그러면 전체 프로그램 은'결과 대기'를 완전히 제거 할 수 있 습 니 다.
    다음은 간단 한 예 를 보 겠 습 니 다.

    이 예 에서 먼저 getPrice()를 바탕 으로 비동기 호출 을 만 든 다음 에 thenAccept()방법 을 사용 하여 후속 작업 을 설정 했다.즉,getPrice()가 실 행 된 후에 후속 처 리 를 하 는 것 이다.
    CompletableFuture 는 일반적인 Future 보다 더욱 실용성 이 있 습 니 다.Future 가 성공 한 후에 자동 으로 다음 작업 을 할 수 있 기 때문에 전체 프로그램 이 막 히 는 곳 이 없 을 것 입 니 다.(즉,Future 의 실행 을 기다 리 지 않 고 Future 가 성공 한 후에 자동 으로 알려 주 는 것 입 니 다)
    위의 코드 를 예 로 들 면 CompletableFuture 의 모든 기능 이 그렇게 신기 한 기능 을 할 수 있 는 것 은 AsyncSupply 류(상기 코드 중의 supply Async()방법 으로 만 든 것)덕분이다.
    AsyncSupply 가 실 행 될 때 다음 과 같 습 니 다.
    
            public void run() {
                CompletableFuture<T> d; Supplier<T> f;
                if ((d = dep) != null && (f = fn) != null) {
                    dep = null; fn = null;
                    if (d.result == null) {
                        try {
                            //             
                            //        ,  d.result   
                            d.completeValue(f.get());
                        } catch (Throwable ex) {
                            d.completeThrowable(ex);
                        }
                    }
                    //     ,      ,        ,    thenAccept()     
                    //      Future      
                    d.postComplete();
                }
            }
    
    d.postComplete()를 계속 보 세 요.여기 서 후속 작업 을 호출 합 니 다.
    
       final void postComplete() {
                    //      ,   tryFire() 
                    // tryFire() ,          ,   thenAccept()    
                    f = (d = h.tryFire(NESTED)) == null ? this : d;
                }
            }
        }
    
    수다
    오늘 우 리 는 주로 Future 모델 을 소개 한다.우 리 는 가장 간단 한 Future 모델 을 시작 으로 점차적으로 깊이 들 어 갔다.선후 로 JDK 내부 의 Future 모델 실현 과 Future 모델 의 진화 버 전 인 CompletableFuture 에 대해 간단 한 소 개 를 했다.맞다.
    다 중 스 레 드 개발 에 있어 Future 모델 의 응용 이 매우 광범 위 하 므 로 이 모델 은 비동기 개발 의 인 프 라 가 되 었 다 고 할 수 있다.
    이상 은 JAVA Future 류 의 사용 에 대한 상세 한 내용 입 니 다.JAVA Future 류 의 사용 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!

    좋은 웹페이지 즐겨찾기