Java Concurrency 패키지를 사용한 친구들은 미래에 익숙 할 수 있습니다 (인터페이스)는 널리 사용되는 동시 설계 모델로, 데이터 흐름 동기화가 필요한 동시 애플리케이션의 개발을 크게 단순화 할 수 있습니다. 미래는 일부 도메인 언어 (예 : Alice ML)에서 구문 수준에서 직접 지원됩니다.
여기서 우리는 java.util.concurrent.future를 예로 들어 미래의 특정 작업 방법에 대해 간략하게 이야기 할 것입니다. 미래의 객체 자체는 비동기 처리 결과에 대한 명시 적 참조로 간주 될 수 있습니다. 비동기 특성으로 인해 제작 초기에 참조하는 객체를 사용할 수 없습니다 (예 : 여전히 작동, 네트워크 전송 또는 대기 중). 이 시점에서 미래를 얻는 프로그램 흐름이 미래에 의해 언급 된 객체를 사용하기 위해 서두르지 않으면, 프로세스가 미래에 참조 해야하는 객체로 이동할 수 있습니다. 두 가지 상황이어야합니다.
이 객체를 사용할 수 있고 관련 후속 프로세스를 완료하고 싶습니다. 실제로 사용할 수없는 경우 다른 지점 프로세스를 입력 할 수도 있습니다.
"당신이 없다면, 내 인생은 그 의미를 잃을 것입니다. 그래서 바다가 사라지더라도, 나는 당신을 기다릴 것입니다. -시간)
전자의 경우, 미래를 호출하여 참조 된 객체가 준비되었는지 여부를 결정할 수 있으며, 후자의 경우, get () 만 호출하면됩니다.
Get (Long Timeout, TimeUnit Unit)는 동기식 차단으로 객체를 준비 할 때까지 기다립니다. 실제 런타임이 차단되거나 즉시 반환되는지 여부는 get ()의 통화 시간과 객체의 순서에 따라 다릅니다.
간단히 말해서, 향후 모드는 지속적인 프로세스에서 데이터 중심의 동시성 요구를 충족시킬 수 있으며, 동시 실행의 성능 향상뿐만 아니라 지속적인 프로세스의 단순성과 우아함도 얻을 수 있습니다.
다른 동시 설계 패턴과 비교
미래 외에도 다른 일반적인 동시성 설계 패턴에는 "콜백 구동 (다중 스레드 환경)", "메시지/이벤트 중심 (배우 모델) 등이 있습니다.
콜백은 가장 일반적인 비동기 동시성 모드로, 즉시 성적이고 간단한 인터페이스 디자인을 갖습니다. 그러나 미래와 비교할 때 그 단점도 매우 분명합니다. 먼저, 멀티 스레드 환경의 콜백은 일반적으로 콜백을 트리거하는 모듈 스레드에서 실행되므로 콜백 메소드의 제공자는이 모듈의 스레드에 있습니다. 비교적 안전하지 않은 사용자 애플리케이션을위한 콜백을 실행합니다. 왜냐하면 콜백 인터페이스를 사용 하여이 모듈의 즉각적인 영향과 신뢰성에 간접적으로 영향을 줄 수있는 예외를 결정할 수 없기 때문입니다 시퀀스. 프로세스 개발, 콜백 메소드의 실행이 분리되므로 정상 프로세스와 병합하기가 어렵습니다. 따라서 콜백 인터페이스는 콜백에서 간단한 작업 만 완료해야하며 다른 프로세스와 결합 할 필요가없는 시나리오에 적합합니다.
위의 콜백 모드의 단점은 정확히 미래의 강점입니다. 미래의 사용은 자연스럽게 비동기 데이터 드라이버를 순차적 인 프로세스에 통합하는 것이기 때문에 스레드 뮤트 문제를 전혀 고려할 필요는 없습니다. 아래에 "게으른 미래"). 반면에 향후 인터페이스를 제공하는 모듈은 콜백 인터페이스와 같은 신뢰성 문제 와이 모듈에 대한 잠재적 인 즉각적인 영향에 대해 걱정할 필요가 없습니다.
또 다른 일반적인 동시 디자인 패턴은 "메시지 (이벤트) 구동"입니다. 이는 일반적으로 액터 모델에서 사용됩니다. 서비스 요청자는 서비스 제공 업체에 메시지를 보내고 서비스 처리 결과에 의존하지 않는 후속 작업을 계속 수행합니다. , 당신이 그것에 의존 해야하는 경우, 현재 프로세스가 종료되면 상태가 기록되며 응답 메시지를 대기 한 후에 기록 된 상태가 트리거됩니다. 이 상태 머신 기반 동시 제어는 콜백보다 연속성 순차적 프로세스에 더 적합하지만 개발자는 비동기 서비스의 호출에 따라 연속 프로세스를 여러 상태 별 하위 프로세스로 줄여야하며, 이는 인위적으로 개발의 복잡성을 증가시킵니다. 미래 모드를 사용하면이 문제를 피할 수 있으며 비동기 통화를 위해 연속 프로세스를 중단 할 필요가 없습니다. 그러나 한 가지에 주목해야합니다. Future.get () 메소드는 스레드 실행을 차단할 수 있으므로 일반적으로 기존의 액터 모델에 직접 통합 될 수 없습니다. (코 루틴 기반 액터 모델은이 갈등을 더 잘 해결할 수 있습니다)
Future의 유연성은 또한 동기화와 비동기 선택 사이의 자유로운 선택에 반영됩니다. 프로세스의 요구. get (timeout)]. 예를 들어, 데이터 준비 여부를 기반 으로이 갭을 사용하여 다른 작업을 완료할지 여부를 결정할 수 있으며, 이는 "비동기 분기 예측"메커니즘을 구현하기에 매우 편리합니다.
미래의 파생물
위에서 언급 한 기본 형식 외에도 Future는 풍부한 파생적 변화가 있으므로 몇 가지 일반적인 변화가 있습니다.
게으른 미래
일반적인 미래와 달리 Lazy Future는 창조 초기에 참조 된 객체를 적극적으로 준비하지는 않지만 해당 작업을 시작하기 전에 물체가 요청 될 때까지 기다립니다. 따라서 게으른 미래 자체는 동시성을 달성하기위한 것이 아니라 불필요한 컴퓨팅 리소스를 출발점으로 절약해야하며 그 효과는 Lambda/Closure와 유사합니다. 예를 들어, 특정 API를 설계 할 때는 정보 세트를 반환해야 할 수 있으며 일부 정보 계산은 상당한 자원을 소비 할 수 있습니다. 그러나 발신자는이 모든 정보에 대해 걱정하지 않을 수 있으므로 게으른 미래의 형태로 더 많은 리소스가 필요한 객체를 제공하면 발신자가 특정 정보를 사용할 필요가 없을 때 리소스를 절약 할 수 있습니다.
또한 Lazy Future는 조기 획득 또는 자원 잠금으로 인한 불필요한 상호 배제를 피하기 위해 사용될 수 있습니다.
약속하다
약속은 미래의 특별한 지점으로 간주 될 수 있습니다. 일반적인 미래는 일반적으로 서비스 호출자가 비동기 처리 프로세스에 직접 연락하는 것입니다. 그러나 약속은 서비스 발신자에 의해 비동기 프로세스가 직접 트리거되지 않는 시나리오를 명시 적으로 표현하는 데 사용됩니다. 예를 들어, 미래의 인터페이스의 타이밍 컨트롤은 발신자에 의해 비동기 프로세스가 트리거되지 않고 Taobao의 분산 구독 프레임 워크에 의해 제공되는 미래의 구독 인터페이스에 의해 트리거됩니다. 가입자이지만 가입자는 언제 데이터를 게시하거나 업데이트합니다. 따라서 표준 미래와 비교하여 Promise Interface에는 일반적으로 추가 SET () 또는 FULFILL () 인터페이스가 있습니다.
재사용 가능한 미래
정기적 인 미래는 일회성이므로 비동기 처리 결과를 얻을 때 미래 객체 자체가 그 의미를 상실합니다. 그러나 특별히 설계된 미래는 재사용 될 수 있으며, 이는 여러 번 변경할 수있는 데이터에 매우 유용합니다. 예를 들어, 위에서 언급 한 Taobao 분산 구독 프레임 워크에서 제공하는 미래 스타일 인터페이스는 waitnext () 메소드를 여러 번 허용합니다 (미래와 동일). 마지막 전화. 또 다른 업데이트가 없으면 다음 데이터 릴리스까지 차단됩니다. 이 디자인의 장점은 인터페이스 사용자가 적절한 시간에 구독 데이터의 변경에 응답하거나 독립 스레드의 무한 루프를 통해 다른 타이밍 작업을 고려하거나 여러 작업을 기다리는 것입니다. 동시에. 미래. 단순화 된 예는 다음과 같습니다.
for (;) {schedule = while> now () {schedure.waitnext (data); .}} DOSCHEDULEDTASK ();} 미래의 사용
먼저, Java에서 코드를 나열하는 것은 코드가 다음과 같습니다.
// String Call () {return "reture of taskwithresult" + id} public static void main (string [] args) {executorService ec = executors.newCachedThreadPool (); 새로운 ArrayList <future <string> (); 노력하다 : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : {// get () 블록은 완료 될 때까지 : System.out.println (fs.get ()) CATCH (InterruptedExcept) {e) {e); : taskwithresult의 result 1의 result의 결과 1의 result 1의 result daskresult 2res ult of task withresult withresult withresult의 4result 4result watchresult withresult waskresult of taskwithresult of taskwithresult 9*/////////////////////////////미래의 사용을 설명하기 위해, 우선, ExecutorService Object Exec Call () 메소드를 호출하여 미래 객체를 생성하여 특정 유형의 호출 가능 리턴 결과를 Parameterize에 사용합니다. iSdone () 메소드를 사용하여 미래가 완료되었는지 여부를 쿼리 할 수 있습니다. 작업이 완료되면 결과가 있으며 결과를 얻으려면 get () 메소드를 호출 할 수 있습니다. 이 경우 isdone () 확인없이 직접 get ()를 호출 할 수 있습니다. 시간 초과로 get () 함수를 호출하거나 먼저 작업이 완료되었는지 확인한 다음 get ()를 호출 할 수 있습니다.