JAVA Future 류 의 사용 에 대한 상세 한 설명
고성능 프로 그래 밍 에서 동시 프로 그래 밍 은 이미 매우 중요 한 부분 이 되 었 다.단일 핵 CPU 의 성능 이 한계 에 이 르 렀 을 때 우 리 는 다 핵 을 통 해 시스템 의 성능 을 한층 더 향상 시 킬 수 밖 에 없 기 때문에 병행 프로 그래 밍 을 탄생 시 켰 다.
직렬 프로 그래 밍 보다 동시 프로 그래 밍 이 더 어렵 고 실수 하기 쉬 우 므 로 우 리 는 선인 들 의 우수한 성숙 한 디자인 모델 을 참고 하여 우리 의 디자인 을 더욱 건장 하고 완벽 하 게 해 야 한다.
한편,Future 모델 은 바로 그 중에서 가장 광범 위 하 게 사용 되 고 매우 중요 한 디자인 모델 이다.오늘 은 병 이와 퓨 처 모드 를 알 아 보 겠 습 니 다!
생활 속 의 Future 모델
퓨 처 모델 을 더 빨리 이해 하기 위해 서 는 삶 의 예 를 살 펴 보 자.
필드 1:
점심 시간 이 되 었 습 니 다.학생 들 은 밥 을 먹 으 러 가 야 합 니 다.왕 군 은 계단 을 내 려 가 20 분 걸 었 습 니 다.KFC 에 왔 습 니 다.주문 하고 줄 을 서 며 밥 을 먹 는 데 모두 20 분 이 걸 렸 습 니 다.그리고 20 분 걸 려 서 회사 로 돌아 가 계속 일 했 습 니 다.모두 1 시간 입 니 다.
장면 2
점심 시간 이 되자 친구 들 이 밥 을 먹 으 러 가 려 고 합 니 다.왕 군 은 KFC 에 게 배달 을 시 켰 습 니 다.곧 주문 서 를 받 았 습 니 다.(주문 서 는 밥 으로 먹 을 수 없 지만 주문 이 있어 서 밥 을 못 먹 을 까 봐 걱정 입 니 다)이 어 왕 군 은 계속 일 을 할 수 있 었 고 30 분 후에 배달 이 도 착 했 습 니 다.이 어 왕 군 은 10 분 동안 밥 을 먹 었 습 니 다.이 어 계속 일 을 할 수 있 게 되 었 고 옆집 왕 군 에 게 성공 적 으로 말 렸 습 니 다.
분명히 이 두 장면 에서 왕 군 은 근무 시간 이 더욱 빡빡 하 다.특히 줄 을 서 는 시간 은 배달 원 에 게 맡 길 수 있 기 때문에 자신의 본업 에 더욱 집중 할 수 있다.똑똑 한 당신 도 이미 깨 달 았 을 것 입 니 다.장면 1 은 전형 적 인 함수 동기 호출 이 고 장면 2 는 전형 적 인 비동기 호출 입 니 다.
한편,장면 2 의 비동기 호출 은 또 하나의 특징 이 있 는데 그것 이 반환 값 을 가지 고 있다 는 것 이다.이 반환 값 은 바로 우리 의 주문 이다.이 주문 서 는 매우 중요 하 다.이 주문 서 를 통 해 우 리 는 현재 이 호출 에 대응 하 는 결 과 를 얻 을 수 있다.
이곳 의 주문 은 Future 모델 의 Future 와 같 습 니 다.이것 은 계약 이 고 약속 입 니 다.주문 서 는 먹 을 수 없 지만 주문 서 를 손 에 쥐 고 먹 을 것 이 없 는 것 을 두려워 하지 않 습 니 다.퓨 처 는 우리 가 원 하 는 결과 가 아니 지만 퓨 처 를 들 고 미래 에 우리 가 원 하 는 결 과 를 얻 을 수 있 습 니 다.
따라서 Future 모드 는 반환 값 이 필요 한 비동기 호출 을 잘 해결 했다.
Future 모드 의 주요 역할
하나의 전형 적 인 Future 모델 은 다음 과 같은 몇 가지 부분 으로 구성 된다.
이 가운데 주목 할 점 은 데이터,리 얼 데이터,퓨 처 데이터 다.이것 은 전형 적 인 대리 모델 로 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()방법 으로 실제 데 이 터 를 얻 는 것 을 제외 하고 보조 적 인 방법 도 제공 합 니 다.예 를 들 어:
//
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 bleFutureFuture 모드 가 좋 지만 문제 가 있 습 니 다.바로 작업 을 스 레 드 에 제출 한 후에 스 레 드 를 호출 하면 이 작업 이 언제 실 행 될 지 모 릅 니 다.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 류 의 사용 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.