단일 스레드 응용 프로그램에서 메소드를 호출 할 때 결과는 계산이 끝나는 경우에만 반환됩니다.
public string downloadContents (url url)는 ioexception {trystream input = url.openstream ()) {return ioutils.tring (input, Standardc harsets.utf_8);}} // ... 최종 미래 <strong> downloadContents (new New New) URL ( "http://www.example.com");
DownloadContents ()는 무해한 것처럼 보이지만 오랫동안 수행해야합니다. 동시에, 지연을 줄이기 위해 대기 결과 동안 다른 작업을 동시에 독립적으로 처리해야 할 수도 있습니다. 과거에는 새 스레드를 시작하거나 결과를 기다릴 수 있습니다 (메모리 공유, 잠금, 잘못 대기 ()/notify () 쌍).
미래의 <t> 모드를 통해 분명해질 것입니다.
공개 정적 미래 <string> startdownloading (url url) {// ...} 최종 미래 <string> contentsFuture = startDownload (new, http : //www.example .com "); // 기타 계산 문자열 contents = contentsfuture .얻다 ();
우리는 STARTDOWNLODING (), startDownloading ()이 차단되지 않지만 외부 사이트가 응답하기를 기다리는 것이 중요합니다. 반대로, 빠르게 돌아와 가벼운 미래의 <string> 객체를 반환하면. 이 객체는 약속이므로 향후 문자열 유형을 사용할 수 있습니다. 그러나 우리는 그것이 언제 될지 알지 못하지만 결과로 돌아올 때 까지이 참조를 유지합니다. 다시 말해, 미래는 실제 대상 객체가 아니라 에이전트 또는 객체 포장입니다. 비동기 계산이 완료되면 추출 할 수 있습니다. 그렇다면 향후 어떤 종류의 인터페이스를 제공합니까?
Future.get ()가 가장 중요한 방법입니다. 약속의 결과가 가능할 때까지 차단하고 기다리 므로이 문자열이 실제로 필요한 경우 get () 메소드에 전화하여 기다리십시오. 시간 초과 매개 변수를 허용하는 무거운로드 버전도 있습니다.
어떤 경우에는 미래가 가능한지 비밀리에 살펴 보는 것일 수도 있습니다. 이것은 isdone ()을 통해 수행 할 수 있습니다. 상황을 상상해보십시오. 사용자가 비동기 계산을 기다리고 있습니다.
최종 미래 <string> contentsFuture = startDownload (new URL ( "http://www.example.com"); while (! contentsfuture.isdone ()) {askusertowail (); somecomputationinthemeantime ();} contentsfuture.get () ;;
마지막으로, Future.get ()의 내용은 차단하지 않고 즉시 반환 할 수 있습니다. 이 모델을 따르면, 당신은 바쁘지 않을 것입니다.
Futrues를 취소하는 것은 우리가 다루지 않은 마지막 것입니다. 비동기 작업을 시작하고 2 초 후에 포기하거나 오류를 전달하거나 임시 솔루션을 사용하여 해결할 수 있다고 상상해보십시오. 그러나 당신은 좋은 시민입니다. 당신은이 미래의 대상을 말해야합니다. 나는 더 이상 당신이 필요하지 않습니다. 당신은 상관하지 않습니다. 그런 다음 구식 작업을 중지하여 리소스를 절약 할 수 있습니다. 문법은 간단합니다.
contentfuture.cancel (true);
우리는 모두 숨기고 싶어합니다. 취소는 두 가지 방법으로 구현 될 수 있습니다. 작업이 시작되기 전에 미래의 결과가 표현되기 전에 계산이 시작되면 오 탐수가 취소됩니다. Callable.call ()가 절반으로 실행되면, 우리는 그것을 끝내면 Future.call ()는 침습적이며 달리기 작업을 방해하려고합니다. 이것이 좋다고 생각하십니까? 현상 중단 된 예고를 던지는 사람들, thread.sleep (), object.wait (), conition.await () 등과 같은 악명 높은 방법,이 방법을 차단하고 일부 사람들이 통화를 취소하기로 결정하더라도 , 그들은 의심 할 여지없이 인터럽트 꺼짐을 던지고, 현재 작업 작업을 방해 할 사람을 보낼 것입니다.
그래서 우리는 이제 미래가 무엇인지 이해합니다 --- 자리 표시 자, 당신은 미래에 대상 객체를 얻을 수 있습니다. 자동차와 마찬가지로 제조의 열쇠는 없습니다. 그러나 응용 프로그램에서 미래의 인스턴스를 어떻게 얻을 수 있습니까? 가장 일반적인 두 가지 자원은 스레드 풀과 비동기 방법 (스레드 풀의 지원)입니다. 따라서 startDownloading () 메소드는 다음과 같이 다시 작성할 수 있습니다.
개인 최종 ExecutorService Pool = Executors.newfixedThreadpool (10); Public Future <string> startDownloading (최종 URL)은 ioException {return Pool.Submit (새 호출 <string> () {@override public String () exception {try (try). inputStream input = url.openstream ()) {return ioutils.toString (input, Standardcharsets.utf_8);});}
지루한 문법 문제가 많이 있지만 기본적인 사고는 간단합니다. 오랫동안 실행 해야하는 포장 컴퓨팅은 조정 가능한 <string>에 포장되며 ()는 스레드 풀에 10을 포함합니다 스레드. 제출 후, Future <string>의 구현은 어떤 식 으로든 작업 및 스레드 풀에 연결하는 것과 같습니다. 분명히 귀하의 작업은 즉시 실행되지 않습니다. 이는 큐에 배치되며 나중에 스레드에 의해 꺼집니다. 중간에 머무르는 작업은 오랫동안 실행중인 작업을 취소 할 수 있지만 이것은 더 복잡한 일입니다.
봄과 EJB에서 미래를 만날 수도 있습니다. 예를 들어 @ASYNC의 주석을 Spring 프레임 워크에 추가 할 수 있습니다.
@asyncpublic future <string> startDownloading (최종 URL)은 ioException {try (inputStream input = url.openStream ()) {return new Asyncres ult <> (ioutils.tostring (input, Standardcharsets.utf_8));
포장 결과를 통해 비동기식을 통해 미래를 구현하지만이 방법 자체는 스레드 풀 또는 처리 된 비동기와 상호 작용하지 않습니다. 나중에 Spring은 STARTDOWNLODING ()에 대한 모든 통화를 나타내고 스레드 풀에서 실행됩니다. EJB에서 @asynchronousAnnotation을 추가하여 동일한 기능이 완료됩니다.