C # async / await와 동일한 Java?


151

저는 일반적인 C # 개발자이지만 때로는 Java로 응용 프로그램을 개발합니다. C # async / await에 해당하는 Java가 있는지 궁금합니다. 간단히 말하면 Java는 다음과 같습니다.

async Task<int> AccessTheWebAsync()
{ 
    HttpClient client = new HttpClient();
    var urlContents = await client.GetStringAsync("http://msdn.microsoft.com");
    return urlContents.Length;
}

7
이것이 좋은 이유 : Miguel de Icaza의 우리 세대의 성명서로서의 콜백 .
andrewdotn

자바의 현재 솔루션은 실제 접두사 값을 처리하지 않는 것입니다 async만, 사용 Future또는 Observable대신 값.
SD

1
동등한 것은 없습니다. 그리고 아파요. 이 두 가지 간단한 단어와 동일한 효과에 도달하지 않고 복잡한 해결 방법과 라이브러리가 필요한 기능이 하나 더 있습니다.
spyro

자바 디자이너들은 오랫동안 자바 바이트 코드를 기존 기능에 대한 라이브러리 및 Syntatic-sugar의 변경 사항과 호환되도록 유지하려고 노력했다는 점은 주목할 가치가 있습니다. 제네릭이 런타임 유형 정보를 저장하지 않고 램더가 인터페이스를 구현하는 객체로 구현된다는 사실을 참조하십시오 . async / await는 바이트 코드를 매우 크게 변경해야하므로 언제든지 Java에서 볼 수는 없습니다.
Philip Couling

답변:


140

아니요, Java 또는 v5 이전의 C #에는 async / await에 해당하는 것이 없습니다.

배후에 상태 머신을 구축하는 것은 상당히 복잡한 언어 기능입니다.

Java에서 비동기 / 동시성에 대한 언어 지원은 상대적으로 거의 없지만 java.util.concurrent패키지에는 이와 관련된 유용한 클래스 가 많이 있습니다 . (작업 병렬 라이브러리와 동일하지는 않지만 가장 가까운 근사값입니다.)


15
@ user960567 : 아니요, 요점은 언어 기능 이라는 것 입니다. 라이브러리에만 배치 할 수는 없습니다. 나는 적어도 Java 8에 대해 예정된 것과 동등한 것이 없다고 생각합니다.
Jon Skeet

10
@ user960567 : 사용중인 C # 버전과 사용중인 .NET 버전을 구별해야합니다. async / await는 C # 5에서 도입 된 언어 기능입니다. 예. Microsoft.Bcl.Async를 사용하여 .NET 4를 대상으로하는 async / await를 사용할 수 있지만 여전히 C # 5 컴파일러를 사용해야합니다.
Jon Skeet

5
@rozar : 아뇨. 비동기에는 이미 여러 가지 옵션이 있지만 RxJava는 C #과 같은 방식으로 언어 를 변경하지 않습니다 . 나는 Rx에 대해 아무것도 없지만 C # 5의 비동기와 동일하지 않습니다.
Jon Skeet

11
@DtechNet : 비동기식 인 많은 JVM 기계가 있습니다. 예 ... 비동기를 지원하는 실제 언어 기능 과는 매우 다릅니다 . (비동기 / 대기 전에 .NET에는 많은 비동기가 있었지만 ... async / await를 사용하면 훨씬 쉽게 이용할 수 있습니다.)
Jon Skeet

1
@ Arkon : 명확한 언어 지원 이 없다면 대답은 여전히 ​​옳습니다. C # 컴파일러가 상태 머신을 빌드하는 모든 방식이 여기서 중요합니다.
Jon Skeet

41

await때 비동기 동작이 완료 (추가의 코드를 실행하는 계속 사용 client.GetStringAsync(...)).

따라서 가장 가까운 근사값으로 CompletableFuture<T>(Java 8 .net Task<TResult>) 기반 솔루션을 사용하여 Http 요청을 비동기 적으로 처리합니다.

2016 년 5 월 25 일에 Abril 13 일에 릴리스 된 AsyncHttpClient v.2로 업데이트 :

따라서 OP 예제와 동등한 Java 8 AccessTheWebAsync()은 다음과 같습니다.

CompletableFuture<Integer> AccessTheWebAsync()
{
    AsyncHttpClient asyncHttpClient = new DefaultAsyncHttpClient();
    return asyncHttpClient
       .prepareGet("http://msdn.microsoft.com")
       .execute()
       .toCompletableFuture()
       .thenApply(Response::getResponseBody)
       .thenApply(String::length);
}

이 사용법은 비동기 HTTP 클라이언트 요청에서 CompletableFuture를 얻는 방법에 대한 답변에서 가져 왔습니다. 이는 2016 년 Abril 13 일에 릴리스 된 AsyncHttpClient 버전 2에서 제공되는 새로운 API에 따라 이미 본질적으로 지원됩니다 CompletableFuture<T>.

AsyncHttpClient 버전 1을 사용한 원본 답변 :

이를 위해 두 가지 가능한 접근 방식이 있습니다.

  • 첫 번째는 비 차단 IO를 사용하고 그것을 호출합니다 AccessTheWebAsyncNio. 그러나 AsyncCompletionHandler함수형 인터페이스가 아닌 추상 클래스 이기 때문에 람다를 인수로 전달할 수 없습니다. 따라서 익명 클래스의 구문으로 인해 불가피한 상세한 표현이 발생합니다. 그러나이 솔루션은 주어진 C # 예제의 실행 흐름에 가장 가깝습니다 .

  • 두 번째는 약간 덜 장황하지만 응답이 완료 될 때까지 스레드를 궁극적으로 차단하는 새 작업 을 제출합니다 f.get().

첫 번째 방법 은 더 장황하지만 비 차단입니다.

static CompletableFuture<Integer> AccessTheWebAsyncNio(){
    final AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
    final CompletableFuture<Integer> promise = new CompletableFuture<>();
    asyncHttpClient
        .prepareGet("https://msdn.microsoft.com")
        .execute(new AsyncCompletionHandler<Response>(){
            @Override
            public Response onCompleted(Response resp) throws Exception {
                promise.complete(resp.getResponseBody().length());
                return resp;
            }
        });
    return promise;
}

두 번째 접근법은 덜 장황하지만 스레드를 차단합니다.

static CompletableFuture<Integer> AccessTheWebAsync(){
    try(AsyncHttpClient asyncHttpClient = new AsyncHttpClient()){
        Future<Response> f = asyncHttpClient
            .prepareGet("https://msdn.microsoft.com")
            .execute();
        return CompletableFuture.supplyAsync(
            () -> return f.join().getResponseBody().length());
    }
}

1
실제로 이것은 행복한 흐름과 같습니다. 마지막으로 예외 처리에 대해서는 다루지 않습니다. 그것들을 포함하면 코드가 훨씬 복잡해지고 오류가 발생하기 쉽습니다.
haimb

1
이것은 연속이 아닙니다. 이 예제에서는 현재 스레드를 해제하여 다른 작업을 실행 한 다음 응답이 도착한 후 현재 스레드에서이 메소드의 실행을 계속하는 async / await의 실제 목적을 놓치고 있습니다. (이것은 UI 스레드가 응답하거나 메모리 사용을 줄이기 위해 필요합니다.)이 예의 기능은 일반 블로킹 스레드 동기화와 일부 콜백입니다.
Aleksandr Dubinsky 21

1
@AleksandrDubinsky 콜백 스레드에서 콜백이 실행되지 않을 수 있음을 지적하면 동의합니다. 네 말이 맞아 스레드 차단에 동의하지 않습니다. 25-05-2016업데이트 된 UPDATED의 답변 은 비 차단입니다.
Miguel Gamboa

1
....이 샘플은 C #이 비동기 작업을 수행 할 때 읽고 쓰는 것이 훨씬 간단한 이유입니다. Java의 고통 일뿐입니다.
spyro

29

Java 바이트 코드를 다시 작성하여 비동기 / 대기를 시뮬레이션하는 ea-async 를 확인하십시오 . 읽어보기 당 : ".NET CLR의 Async-Await에서 많은 영향을 받았습니다"


8
누구나 프로덕션에 사용합니까?
Next Door에서 Mr.Wang

1
EA는 생산에 적합하지 않은 것에 돈을 쓰지 않을 것이라고 생각합니다.
BrunoJCM

1
무언가에 돈을 쓴 다음 생산에 적합하지 않다고 결정하는 것은 매우 정상적인 일입니다. 그것이 배울 수있는 유일한 방법입니다. 프로덕션 환경에서 Java 에이전트 설정없이 사용할 수 있습니다. 막대를 약간 낮추어야합니다 ( github.com/electronicarts/ea-async ).
thoredge

16

asyncawait 는 구문 설탕입니다. 비동기 및 대기의 본질은 상태 머신입니다. 컴파일러는 async / await 코드를 상태 머신으로 변환합니다.

동시에 실제 프로젝트에서 async / await를 실제로 구현하려면 이미 많은 비동기 I / O 라이브러리 함수 가 있어야합니다 . C #의 경우 대부분의 원래 동기화 된 I / O 기능에는 대체 비동기 버전이 있습니다. 이러한 비동기 함수가 필요한 이유는 대부분의 경우 자체 비동기 / 대기 코드가 일부 라이브러리 비동기 메소드로 요약되기 때문입니다.

C #의 비동기 버전 라이브러리 함수는 Java의 AsynchronousChannel 개념과 비슷합니다. 예를 들어, 읽기 작업이 완료된 후 Future를 반환하거나 콜백을 실행할 수있는 AsynchronousFileChannel.read가 있습니다. 그러나 정확히 동일하지는 않습니다. 모든 C # 비동기 함수는 작업을 반환합니다 (미래와 비슷하지만 미래보다 더 강력 함).

Java가 async / await를 지원한다고 가정하면 다음과 같은 코드를 작성합니다.

public static async Future<Byte> readFirstByteAsync(String filePath) {
    Path path = Paths.get(filePath);
    AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

    ByteBuffer buffer = ByteBuffer.allocate(100_000);
    await channel.read(buffer, 0, buffer, this);
    return buffer.get(0);
}

그런 다음 컴파일러가 원래 async / await 코드를 다음과 같이 변환한다고 상상할 수 있습니다.

public static Future<Byte> readFirstByteAsync(String filePath) {

    CompletableFuture<Byte> result = new CompletableFuture<Byte>();

    AsyncHandler ah = new AsyncHandler(result, filePath);

    ah.completed(null, null);

    return result;
}

다음은 AsyncHandler의 구현입니다.

class AsyncHandler implements CompletionHandler<Integer, ByteBuffer>
{
    CompletableFuture<Byte> future;
    int state;
    String filePath;

    public AsyncHandler(CompletableFuture<Byte> future, String filePath)
    {
        this.future = future;
        this.state = 0;
        this.filePath = filePath;
    }

    @Override
    public void completed(Integer arg0, ByteBuffer arg1) {
        try {
            if (state == 0) {
                state = 1;
                Path path = Paths.get(filePath);
                AsynchronousFileChannel channel = AsynchronousFileChannel.open(path);

                ByteBuffer buffer = ByteBuffer.allocate(100_000);
                channel.read(buffer, 0, buffer, this);
                return;
            } else {
                Byte ret = arg1.get(0);
                future.complete(ret);
            }

        } catch (Exception e) {
            future.completeExceptionally(e);
        }
    }

    @Override
    public void failed(Throwable arg0, ByteBuffer arg1) {
        future.completeExceptionally(arg0);
    }
}

15
합성 설탕? 비동기 코드 주위에 예외를 래핑하는 방법과 비동기 코드 주위를 반복하는 방법에 대한 아이디어가 있습니까?
Akash Kava

39
수업도 구문 설탕입니다. 컴파일러는 일반적으로 완전히 자동으로 직접 작성하는 함수 포인터의 모든 트리와 목록을 만듭니다. 이 기능들 / 방법들도 구문 설탕입니다. 그들은 당신이 평소에 쓰는 모든 프로그래머를 자동으로 생성하며 실제 프로그래머가 직접 작성합니다. 어셈블러도 구문 설탕입니다. 실제 프로그래머는 수동으로 머신 코드를 작성하여 수동으로 모든 대상 아키텍처에 이식합니다.
yeoman

32
abou itt를 생각하면, 컴퓨터 자체는 l4m3 n00bz의 구문 설탕입니다. 실제 프로그래머는 작은 집적 회로를 목재 보드에 납땜하고 회로 보드는 대량 생산, 신발 또는 식품과 같은 구문 설탕이기 때문에 금선으로 연결합니다.
yeoman

14

언어 수준의 Java에서는 C # async / await에 해당하지 않습니다. 로 알려진 개념 섬유는 일명 협력 스레드 일명 가벼운 스레드 흥미로운 대안이 될 수있다. 파이버에 대한 지원을 제공하는 Java 라이브러리를 찾을 수 있습니다.

파이버를 구현하는 Java 라이브러리

섬유에 대한 훌륭한 소개를 위해이 기사 (Quasar에서) 를 읽을 수 있습니다 . 여기에는 스레드가 무엇인지, JVM에서 파이버를 구현하는 방법 및 Quasar 관련 코드가 있습니다.


10
C #에서 async / await는 Fibre가 아닙니다. Task콜백을 등록하여 Promise ( 클래스) 에서 연속을 사용하는 컴파일러 마술 일뿐 입니다.
UltimaWeapon 5

1
@UltimaWeapon 그렇다면 섬유는 무엇이라고 생각하십니까?
Aleksandr Dubinsky

@AleksandrDubinsky 예 중 하나는 고 루틴입니다.
UltimaWeapon

1
@ UltimaWeapon 나는 설명을 찾고 있었다.
Aleksandr Dubinsky

@AleksandrDubinsky 나는 그것을 설명하기 위해 게으르다. 정말로 알고 싶다면 goroutine의 후드 아래에서 기사를 검색하십시오.
UltimaWeapon

8

언급했듯이 직접 동등한 것은 없지만 Java 바이트 코드 수정 (비동기 / 대기 유사 명령어 및 기본 연속 구현 모두)을 사용하여 매우 가까운 근사치를 만들 수 있습니다.

JavaFlow 연속 라이브러리 위에 async / await를 구현하는 프로젝트에서 지금 작업하고 있습니다. https://github.com/vsilaev/java-async-await 를 확인 하십시오.

Maven mojo가 아직 작성되지 않았지만 제공된 Java 에이전트로 예제를 실행할 수 있습니다. async / await 코드는 다음과 같습니다.

public class AsyncAwaitNioFileChannelDemo {

public static void main(final String[] argv) throws Exception {

    ...
    final AsyncAwaitNioFileChannelDemo demo = new AsyncAwaitNioFileChannelDemo();
    final CompletionStage<String> result = demo.processFile("./.project");
    System.out.println("Returned to caller " + LocalTime.now());
    ...
}


public @async CompletionStage<String> processFile(final String fileName) throws IOException {
    final Path path = Paths.get(new File(fileName).toURI());
    try (
            final AsyncFileChannel file = new AsyncFileChannel(
                path, Collections.singleton(StandardOpenOption.READ), null
            );              
            final FileLock lock = await(file.lockAll(true))
        ) {

        System.out.println("In process, shared lock: " + lock);
        final ByteBuffer buffer = ByteBuffer.allocateDirect((int)file.size());

        await( file.read(buffer, 0L) );
        System.out.println("In process, bytes read: " + buffer);
        buffer.rewind();

        final String result = processBytes(buffer);

        return asyncResult(result);

    } catch (final IOException ex) {
        ex.printStackTrace(System.out);
        throw ex;
    }
}

@async는 메소드를 비동기 실행 파일로 플래그 지정하는 주석이고, await ()는 연속을 사용하여 CompletableFuture를 대기하는 함수이며 "return asyncResult (someValue)"호출은 연관된 CompletableFuture / Continuation을 마무리하는 것입니다

C #과 마찬가지로 제어 흐름이 유지되고 예외 처리가 규칙적인 방식으로 수행 될 수 있습니다 (시퀀스 실행 코드와 같은 시도 / 캐치)


6

Java 자체에는 동등한 기능이 없지만 Kilim 과 같은 유사한 기능을 제공하는 타사 라이브러리가 있습니다 .


3
이 라이브러리에는 async / await와 관련이 없다고 생각합니다.
Natan

5

먼저 async / await가 무엇인지 이해하십시오. 단일 스레드 GUI 응용 프로그램이나 효율적인 서버가 단일 스레드에서 여러 개의 "섬유"또는 "공동 루틴"또는 "경량 스레드"를 실행하는 방법입니다.

일반 스레드를 사용하는 것이 좋다면 Java에 해당하는 것은 ExecutorService.submitFuture.get입니다. 작업이 완료 될 때까지 차단하고 결과를 반환합니다. 한편, 다른 스레드가 작동 할 수 있습니다.

파이버와 같은 이점을 원한다면 컨테이너 (GUI 이벤트 루프 또는 서버 HTTP 요청 핸들러에서 의미) 또는 직접 작성하여 지원해야합니다.

예를 들어, Servlet 3.0은 비동기 처리를 제공합니다. JavaFX는 다음을 제공합니다 javafx.concurrent.Task. 그러나 이것들은 언어 기능의 우아함을 가지고 있지 않습니다. 그들은 일반적인 콜백을 통해 작동합니다.


2
다음은이 답변의 첫 번째 단락 인 // start quote를 다시 시작하는 기사 인용입니다. Windows Store, Windows 데스크톱 및 Windows Phone 앱과 같은 클라이언트 응용 프로그램의 경우 비동기의 주요 이점은 응답 성입니다. 이러한 유형의 앱은 주로 비동기식으로 사용하여 UI 응답 성을 유지합니다. 서버 응용 프로그램의 경우 비동기의 주요 이점은 확장 성입니다. msdn.microsoft.com/ko-kr/magazine/dn802603.aspx
granadaCoder

3

async / await 키워드와 같이이 작업을 수행 할 수있는 Java 기본 기능은 없지만 실제로 원하는 경우 수행 할 수있는 작업은 CountDownLatch 입니다. 당신이 후 모방 비동기 / await를 (Java7 적어도)이 약을 전달하여. 이것은 안드로이드 단위 테스트에서 일반적으로 처리하는 비동기 호출 (보통 처리기가 게시 한 실행 가능)을 한 다음 결과를 기다립니다 (카운트 다운).

그러나 테스트와 달리 응용 프로그램 내에서 이것을 사용 하는 것은 내가 권장하는 것이 아닙니다 . CountDownLatch는 올바른 횟수와 장소를 효과적으로 카운트 다운하는 데 달려 있기 때문에 매우 까다로울 것입니다.


3

Java async / await 라이브러리를 만들고 출시했습니다. https://github.com/stofu1234/kamaitachi

이 라이브러리는 컴파일러 확장이 필요하지 않으며 Java에서 스택리스 IO 처리를 실현합니다.

    async Task<int> AccessTheWebAsync(){ 
        HttpClient client= new HttpClient();
        var urlContents= await client.GetStringAsync("http://msdn.microsoft.com");
       return urlContents.Length;
    }

   ↓

    //LikeWebApplicationTester.java
    BlockingQueue<Integer> AccessTheWebAsync() {
       HttpClient client = new HttpClient();
       return awaiter.await(
            () -> client.GetStringAsync("http://msdn.microsoft.com"),
            urlContents -> {
                return urlContents.length();
            });
    }
    public void doget(){
        BlockingQueue<Integer> lengthQueue=AccessTheWebAsync();
        awaiter.awaitVoid(()->lengthQueue.take(),
            length->{
                System.out.println("Length:"+length);
            }
            );
    }

1

Java는 불행히도 async / await에 해당하는 것이 없습니다. 구아바의 ListenableFuture와 리스너 체인을 사용하면 가장 근접 할 수 있지만 중첩 수준이 매우 빠르게 증가하기 때문에 여러 비동기 호출이 포함 된 사례를 작성하는 것은 여전히 ​​번거로운 작업입니다.

JVM 위에서 다른 언어를 사용하는 것이 좋으면 다행히도 Scala에는 async / await가 있으며 이는 거의 동일한 구문 및 의미와 동일한 C # async / await입니다. https://github.com/scala/ 비동기 /

이 기능은 C #에서 상당히 고급 컴파일러 지원이 필요했지만 Scala에서는 Scala의 매우 강력한 매크로 시스템 덕분에 라이브러리로 추가 될 수 있으므로 2.10과 같은 이전 버전의 Scala에도 추가 될 수 있습니다. 또한 Scala는 Java와 클래스 호환되므로 Scala로 비동기 코드를 작성한 다음 Java에서 호출 할 수 있습니다.

Akka Dataflow http://doc.akka.io/docs/akka/2.3-M1/scala/dataflow.html 이라는 다른 유사한 프로젝트도 있지만 다른 단어를 사용하지만 개념적으로는 매우 유사하지만 매크로가 아닌 구분 된 연속을 사용하여 구현됩니다. (2.9와 같은 오래된 스칼라 버전에서도 작동합니다).


1

Java에는 async / await라는 C # 언어 기능과 동등한 기능이 없지만 async / await에서 해결하려는 문제에 대한 다른 접근 방식이 있습니다. 이를 프로젝트 Loom 이라고하며 처리량이 많은 동시 처리를위한 가상 스레드를 제공합니다. OpenJDK의 향후 버전에서 제공 될 예정입니다.

이 접근법은 또한 async / await가 가지고있는 " 컬러 함수 문제 "를 해결 합니다.

Golang ( goroutines ) 에서도 비슷한 기능을 찾을 수 있습니다 .


0

java에서 async / await와 동일한 효과를 시뮬레이트하는 깨끗한 코드 직후에 테스트와 같이 완료 될 때까지 스레드를 차단하지 않아도되는 경우 다음 코드와 같은 것을 사용할 수 있습니다.

interface Async {
    void run(Runnable handler);
}

static void await(Async async) throws InterruptedException {

    final CountDownLatch countDownLatch = new CountDownLatch(1);
    async.run(new Runnable() {

        @Override
        public void run() {
            countDownLatch.countDown();
        }
    });
    countDownLatch.await(YOUR_TIMEOUT_VALUE_IN_SECONDS, TimeUnit.SECONDS);
}

    await(new Async() {
        @Override
        public void run(final Runnable handler) {
            yourAsyncMethod(new CompletionHandler() {

                @Override
                public void completion() {
                    handler.run();
                }
            });
        }
    });

0

AsynHelper Java 라이브러리에는 이러한 비동기 호출 (및 대기)을위한 유틸리티 클래스 / 메소드 세트가 포함되어 있습니다.

메소드 호출 또는 코드 블록 세트를 비동기식으로 실행하려는 경우 아래 스 니펫과 같이 유용한 헬퍼 메소드 AsyncTask .submitTasks가 포함 됩니다.

AsyncTask.submitTasks(
    () -> getMethodParam1(arg1, arg2),
    () -> getMethodParam2(arg2, arg3)
    () -> getMethodParam3(arg3, arg4),
    () -> {
             //Some other code to run asynchronously
          }
    );

모든 비동기 코드가 실행을 완료 할 때까지 기다리려면 AsyncTask.submitTasksAndWait 변수를 사용할 수 있습니다.

또한 각 비동기 메서드 호출 또는 코드 블록에서 반환 값을 얻으려면 AsyncSupplier .submitSuppliers 를 사용하여 메서드에서 반환 한 결과 공급자 배열에서 결과를 얻을 수 있습니다. 다음은 샘플 스 니펫입니다.

Supplier<Object>[] resultSuppliers = 
   AsyncSupplier.submitSuppliers(
     () -> getMethodParam1(arg1, arg2),
     () -> getMethodParam2(arg3, arg4),
     () -> getMethodParam3(arg5, arg6)
   );

Object a = resultSuppliers[0].get();
Object b = resultSuppliers[1].get();
Object c = resultSuppliers[2].get();

myBigMethod(a,b,c);

각 메소드의 리턴 유형이 다르면 아래 스 니펫을 사용하십시오.

Supplier<String> aResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam1(arg1, arg2));
Supplier<Integer> bResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam2(arg3, arg4));
Supplier<Object> cResultSupplier = AsyncSupplier.submitSupplier(() -> getMethodParam3(arg5, arg6));

myBigMethod(aResultSupplier.get(), bResultSupplier.get(), cResultSupplier.get());

비동기 메소드 호출 / 코드 블록의 결과는 아래 스 니펫과 동일한 스레드 또는 다른 스레드의 다른 코드 지점에서 얻을 수도 있습니다.

AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam1(arg1, arg2), "a");
AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam2(arg3, arg4), "b");
AsyncSupplier.submitSupplierForSingleAccess(() -> getMethodParam3(arg5, arg6), "c");


//Following can be in the same thread or a different thread
Optional<String> aResult = AsyncSupplier.waitAndGetFromSupplier(String.class, "a");
Optional<Integer> bResult = AsyncSupplier.waitAndGetFromSupplier(Integer.class, "b");
Optional<Object> cResult = AsyncSupplier.waitAndGetFromSupplier(Object.class, "c");

 myBigMethod(aResult.get(),bResult.get(),cResult.get());
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.