Tương đương Java của C # async / đang chờ?


151

Tôi là một nhà phát triển C # bình thường nhưng thỉnh thoảng tôi phát triển ứng dụng trong Java. Tôi đang tự hỏi liệu có bất kỳ Java tương đương với C # async / await không? Nói một cách đơn giản, java tương đương với cái gì:

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

7
Tại sao điều này sẽ tốt đẹp: Cuộc gọi lại như Tuyên bố đi đến thế hệ của chúng tôi bởi Miguel de Icaza.
andrewdotn

Giải pháp hiện tại của Java là không xử lý các giá trị thực tế có tiền tố async, nhưng sử dụng Futurehoặc Observablethay thế các giá trị.
SD

1
Không có tương đương. Và nó đau. Thêm một tính năng thiếu mà bạn cần các cách giải quyết và thư viện phức tạp, mà không bao giờ đạt được hiệu quả tương tự như hai từ đơn giản này.
spyro

Điều đáng chú ý là trong một thời gian dài, các nhà thiết kế Java đã cố gắng giữ cho mã byte Java tương thích ngược với chỉ các thay đổi đối với các thư viện và Syntatic-sugar xung quanh các tính năng hiện có. Xem thực tế rằng thuốc generic không lưu trữ thông tin loại thời gian chạy và các lambder được triển khai như là đối tượng thực hiện giao diện . async / await sẽ yêu cầu những thay đổi rất lớn đối với mã byte là có thể và do đó tôi sẽ không mong đợi được thấy nó trong java bất cứ lúc nào.
Philip Couling

Câu trả lời:


140

Không, không có bất kỳ tương đương nào của async / await trong Java - hoặc thậm chí trong C # trước v5.

Đây là một tính năng ngôn ngữ khá phức tạp để xây dựng một bộ máy trạng thái đằng sau hậu trường.

Có tương đối ít hỗ trợ ngôn ngữ cho sự không đồng bộ / đồng thời trong Java, nhưng java.util.concurrentgói chứa rất nhiều lớp hữu ích xung quanh điều này. (Không hoàn toàn tương đương với Thư viện song song nhiệm vụ, nhưng gần đúng nhất với nó.)


15
@ user960567: Không, quan điểm của tôi là đó là một tính năng ngôn ngữ - nó không thể được đưa vào các thư viện. Tôi không tin rằng có bất kỳ tương đương nào được lên lịch cho Java 8 ít nhất.
Jon Skeet

10
@ user960567: Bạn cần phân biệt giữa phiên bản C # bạn đang sử dụng và phiên bản .NET bạn đang sử dụng. async / await là một tính năng ngôn ngữ - nó được giới thiệu trong C # 5. Có, bạn có thể sử dụng Microsoft.Bcl.Async để sử dụng async / await nhắm mục tiêu .NET 4, nhưng bạn vẫn phải sử dụng trình biên dịch C # 5.
Jon Skeet

5
@rozar: Không, không thực sự. Đã có nhiều tùy chọn cho tính không đồng bộ - nhưng RxJava không thay đổi ngôn ngữ theo cách mà C # đã làm. Tôi không có gì chống lại Rx, nhưng nó không giống với async trong C # 5.
Jon Skeet

11
@DtechNet: Vâng, có rất nhiều máy móc JVM không đồng bộ, vâng ... điều đó rất khác so với việc có các tính năng ngôn ngữ thực tế hỗ trợ không đồng bộ mặc dù. (Có rất nhiều sự không đồng bộ trong .NET trước khi async / chờ đợi, quá ... nhưng async / làm cho chờ đợi nó xa dễ dàng hơn để tận dụng lợi thế về điều đó.)
Jon Skeet

1
@Aarkon: Tôi sẽ lập luận rằng trừ khi có hỗ trợ ngôn ngữ rõ ràng , câu trả lời vẫn đúng. Đây không chỉ là vấn đề của các thư viện giúp việc lập lịch trình đơn giản hơn - toàn bộ cách trình biên dịch C # xây dựng một máy trạng thái rất quan trọng ở đây.
Jon Skeet

41

Việc awaitsử dụng tiếp tục để thực thi mã bổ sung khi hoạt động không đồng bộ hoàn thành ( client.GetStringAsync(...)).

Vì vậy, vì gần đúng nhất, tôi sẽ sử dụng một giải pháp dựa trên CompletableFuture<T>(Java 8 tương đương với .net Task<TResult>) để xử lý yêu cầu http không đồng bộ.

CẬP NHẬT vào ngày 25-05-2016 lên AsyncHttpClient v.2 được phát hành vào ngày Abril ngày 13 năm 2016:

Vì vậy, Java 8 tương đương với ví dụ OP AccessTheWebAsync()là như sau:

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

Cách sử dụng này được lấy từ câu trả lời cho Làm cách nào để tôi có được CompleteableFuture từ yêu cầu Async http Client? và theo API mới được cung cấp trong phiên bản 2 của AsyncHttpClient được phát hành trên Abril ngày 13 năm 2016, đã hỗ trợ nội tại cho CompletableFuture<T>.

Câu trả lời gốc sử dụng phiên bản 1 của AsyncHttpClient:

Cuối cùng, chúng ta có hai cách tiếp cận có thể:

  • cái đầu tiên sử dụng IO không chặn và tôi gọi nó AccessTheWebAsyncNio. Tuy nhiên, vì AsyncCompletionHandlerlà một lớp trừu tượng (thay vì giao diện chức năng), chúng ta không thể vượt qua lambda làm đối số. Vì vậy, nó phát sinh trong tính dài dòng không thể tránh khỏi do cú pháp của các lớp ẩn danh. Tuy nhiên, giải pháp này gần nhất với luồng thực hiện của ví dụ C # đã cho .

  • cái thứ hai thì hơi dài dòng một chút, tuy nhiên nó sẽ gửi một Nhiệm vụ mới mà cuối cùng sẽ chặn một chuỗi f.get()cho đến khi phản hồi hoàn tất.

Cách tiếp cận đầu tiên , dài dòng hơn nhưng không chặn:

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;
}

Cách tiếp cận thứ hai ít dài dòng hơn nhưng chặn một chuỗi:

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
Trên thực tế, đó là tương đương với dòng chảy hạnh phúc. Nó không bao gồm xử lý các trường hợp ngoại lệ, cuối cùng và những người khác. Bao gồm chúng sẽ làm cho mã phức tạp hơn nhiều và dễ bị lỗi hơn.
haimb

1
Đây không phải là một sự tiếp tục. Ví dụ này bỏ lỡ mục đích thực sự của async / await, đó là giải phóng luồng hiện tại để thực thi các thứ khác và sau đó tiếp tục thực hiện phương thức này trên luồng hiện tại sau khi có phản hồi. (Điều này là cần thiết để luồng UI được phản hồi hoặc để giảm mức sử dụng bộ nhớ.) Ví dụ này làm gì là đồng bộ hóa luồng chặn đơn giản, cộng với một số cuộc gọi lại.
Alexanderr Dubinsky

1
@AleksandrDubinsky Tôi đồng ý với bạn khi bạn chỉ ra rằng cuộc gọi lại có thể không chạy trên chuỗi người gọi. Bạn đúng rồi. Tôi không đồng ý về việc chặn một chủ đề. Câu trả lời cập nhật của tôi về CẬP NHẬT vào ngày 25-05-2016 là không chặn.
Miguel Gamboa

1
.... và mẫu này chính xác là lý do tại sao C # đơn giản hơn nhiều để viết và đọc khi thực hiện các công cụ không đồng bộ. Nó chỉ là một nỗi đau trong Java.
spyro

29

Hãy xem ea-async mà Java viết lại mã byte để mô phỏng async / đang chờ khá độc đáo. Theo người đọc của họ: "Nó được truyền cảm hứng rất nhiều từ Async-Await trên .NET CLR"


8
Có ai sử dụng nó trong sản xuất?
Mr.Wang từ Next Door

1
Có vẻ như EA cũng vậy, tôi không nghĩ họ sẽ chi tiền cho những thứ không phù hợp với sản xuất.
BrunoJCM

1
Việc chi tiền cho một thứ gì đó khá bình thường và sau đó quyết định rằng nó không phù hợp để sản xuất; đó là cách duy nhất để học Có thể sử dụng nó mà không cần cài đặt tác nhân java trong sản xuất; nên hạ thanh xuống một chút ( github.com/electronicarts/ea-async ).
thoredge

16

asyncawait là đường cú pháp. Bản chất của async và await là máy trạng thái. Trình biên dịch sẽ chuyển đổi mã async / await của bạn thành một máy trạng thái.

Đồng thời, để async / await thực sự có thể thực hiện được trong các dự án thực tế, chúng ta cần phải có rất nhiều chức năng thư viện I / O Async đã có. Đối với C #, hầu hết các chức năng I / O được đồng bộ hóa ban đầu đều có phiên bản Async thay thế. Lý do chúng tôi cần các hàm Async này là vì trong hầu hết các trường hợp, mã async / await của riêng bạn sẽ chuyển sang một số phương thức Async thư viện.

Các hàm thư viện phiên bản Async trong C # giống như khái niệm AsynyncousChannel trong Java. Ví dụ: chúng tôi có AsynyncousFileChannel.read có thể trả về Tương lai hoặc thực hiện gọi lại sau khi thao tác đọc được thực hiện. Nhưng nó không hoàn toàn giống nhau. Tất cả các chức năng Cync Async trả về Nhiệm vụ (tương tự Tương lai nhưng mạnh hơn Tương lai).

Vì vậy, giả sử Java hỗ trợ async / await và chúng tôi viết một số mã như thế này:

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);
}

Sau đó, tôi sẽ tưởng tượng trình biên dịch sẽ chuyển đổi mã async / await ban đầu thành một cái gì đó như thế này:

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;
}

Và đây là cách triển khai cho 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
Đường tổng hợp? Bạn có ý tưởng nào về cách bọc ngoại lệ xung quanh mã async và các vòng lặp xung quanh mã async không?
Akash Kava

39
Các lớp học cũng vậy, là cú pháp đường. Trình biên dịch tạo tất cả các cây và danh sách các con trỏ hàm mà bạn thường viết bằng tay cho bạn hoàn toàn tự động. Những chức năng / phương pháp này là cú pháp đường, quá. Họ tự động tạo ra tất cả các gotos bạn thường làm, là một lập trình viên thực thụ, viết bằng tay. Trình biên dịch là cú pháp đường, quá. Các lập trình viên thực sự tự viết mã máy và chuyển nó thủ công tới tất cả các kiến ​​trúc đích.
yeoman

32
Suy nghĩ abou itt, bản thân máy tính chỉ là cú pháp đường cho l4m3 n00bz. Các lập trình viên thực sự hàn chúng các mạch tích hợp nhỏ xíu vào một bảng gỗ và kết nối chúng với dây vàng vì bảng mạch là đường cú pháp, giống như sản xuất hàng loạt, giày hoặc thực phẩm.
yeoman

14

Không có tương đương với C # async / await trong Java ở cấp độ ngôn ngữ. Một khái niệm được gọi là Fibers aka chủ đề hợp tác hay chủ đề nhẹ có thể là một sự thay thế thú vị. Bạn có thể tìm thấy các thư viện Java cung cấp hỗ trợ cho các sợi.

Các thư viện Java triển khai Fibers

Bạn có thể đọc bài viết này (từ Quasar) để có phần giới thiệu hay về sợi. Nó bao gồm các luồng là gì, làm thế nào các sợi có thể được thực hiện trên JVM và có một số mã cụ thể Quasar.


10
async / await trong C # không phải là Fiber. Nó chỉ là trình biên dịch ma thuật sử dụng tiếp tục trên Promise ( Tasklớp) bằng cách đăng ký gọi lại.
UltimaWeapon

1
@UltimaWeapon Vậy bạn nghĩ gì về sợi?
Alexanderr Dubinsky

@AleksandrDubinsky Một trong những ví dụ là goroutine.
UltimaWeapon

1
@UltimaWeapon Tôi đang tìm một lời giải thích.
Alexanderr Dubinsky

@AleksandrDubinsky Tôi lười giải thích nó. Nếu bạn thực sự muốn biết, bạn có thể tìm kiếm bài viết về phần dưới của goroutine.
UltimaWeapon

8

Như đã đề cập, không có tương đương trực tiếp, nhưng gần đúng rất gần có thể được tạo bằng các sửa đổi mã byte của Java (đối với cả các hướng dẫn giống như async / await và triển khai tiếp tục cơ bản).

Hiện tôi đang làm việc với một dự án triển khai async / đang chờ trên thư viện tiếp tục JavaFlow , vui lòng kiểm tra https://github.com/vsilaev/java-async-await

Chưa có mojo Maven nào được tạo, nhưng bạn có thể chạy các ví dụ với tác nhân Java được cung cấp. Đây là cách mã async / await trông như thế nào:

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 là chú thích gắn cờ một phương thức là có thể thực thi không đồng bộ, await () là một hàm chờ trên CompleteableFuture bằng cách sử dụng liên tục và một lệnh gọi "return asyncResult (someValue)"

Cũng như C #, luồng điều khiển được giữ nguyên và xử lý ngoại lệ có thể được thực hiện theo cách thông thường (thử / bắt như trong mã được thực hiện tuần tự)


6

Bản thân Java không có các tính năng tương đương, nhưng các thư viện của bên thứ ba tồn tại có chức năng tương tự, ví dụ Kilim .


3
Tôi không nghĩ rằng thư viện này có bất cứ điều gì để làm với những gì async / await làm.
Natan

5

Đầu tiên, hiểu async / await là gì. Đó là cách để một ứng dụng GUI đơn luồng hoặc máy chủ hiệu quả chạy nhiều "sợi" hoặc "đồng tuyến" hoặc "luồng nhẹ" trên một luồng.

Nếu bạn ổn với việc sử dụng các luồng thông thường, thì tương đương Java là ExecutorService.submitFuture.get. Điều này sẽ chặn cho đến khi nhiệm vụ hoàn thành và trả về kết quả. Trong khi đó, các chủ đề khác có thể làm việc.

Nếu bạn muốn lợi ích của một cái gì đó như sợi, bạn cần hỗ trợ trong bộ chứa (ý tôi là trong vòng lặp sự kiện GUI hoặc trong trình xử lý yêu cầu HTTP của máy chủ) hoặc bằng cách viết riêng của bạn.

Ví dụ: Servlet 3.0 cung cấp xử lý không đồng bộ. Cung cấp JavaFX javafx.concurrent.Task. Chúng không có sự thanh lịch của các tính năng ngôn ngữ, mặc dù. Họ làm việc thông qua các cuộc gọi lại thông thường.


2
Dưới đây là trích dẫn bài viết khởi động lại đoạn đầu tiên của câu trả lời này // bắt đầu trích dẫn Đối với các ứng dụng khách, như Windows Store, máy tính để bàn Windows và ứng dụng Windows Phone, lợi ích chính của async là khả năng đáp ứng. Các loại ứng dụng này sử dụng async chủ yếu để giữ cho giao diện người dùng phản ứng nhanh. Đối với các ứng dụng máy chủ, lợi ích chính của async là khả năng mở rộng. msdn.microsoft.com/en-us/magazine/dn802603.aspx
granadaCoder

3

Không có bất cứ thứ gì có nguồn gốc từ java cho phép bạn làm điều này như async / await các từ khóa, nhưng những gì bạn có thể làm nếu bạn thực sự muốn sử dụng CountDownLatch . Sau đó, bạn có thể bắt chước async / await bằng cách chuyển cái này xung quanh (ít nhất là trong Java7). Đây là một thực tiễn phổ biến trong thử nghiệm đơn vị Android, nơi chúng tôi phải thực hiện cuộc gọi không đồng bộ (thường là một cuộc chạy được đăng bởi một người xử lý), và sau đó chờ kết quả (đếm ngược).

Tuy nhiên, việc sử dụng này trong ứng dụng của bạn trái ngược với thử nghiệm của bạn KHÔNG phải là điều tôi khuyên dùng. Điều đó sẽ vô cùng tồi tệ vì CountDownLatch phụ thuộc vào bạn một cách hiệu quả đếm ngược đúng số lần và đúng nơi.


3

Tôi tạo và phát hành Java async / await library. https://github.com/stofu1234/kamaitachi

Thư viện này không cần phần mở rộng trình biên dịch và nhận ra xử lý IO không có chồng trong Java.

    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

Thật không may, Java không có tương đương với async / await. Gần nhất bạn có thể nhận được có lẽ là với ListenableFuture từ Guava và người nghe xâu chuỗi, nhưng sẽ vẫn rất khó viết khi viết cho các trường hợp liên quan đến nhiều cuộc gọi không đồng bộ, vì mức độ lồng sẽ tăng rất nhanh.

Nếu bạn ổn với việc sử dụng một ngôn ngữ khác trên JVM, thì may mắn thay, có một async / await trong Scala, đó là một C # async / await trực tiếp tương đương với một cú pháp và ngữ nghĩa gần như giống hệt nhau: https://github.com/scala/ không đồng bộ /

Lưu ý rằng mặc dù chức năng này cần hỗ trợ trình biên dịch khá tiên tiến trong C #, nhưng trong Scala, nó có thể được thêm vào dưới dạng thư viện nhờ hệ thống macro rất mạnh trong Scala và do đó có thể được thêm ngay cả vào các phiên bản Scala cũ hơn như 2.10. Ngoài ra, Scala tương thích với lớp với Java, vì vậy bạn có thể viết mã async trong Scala và sau đó gọi nó từ Java.

Ngoài ra còn có một dự án tương tự khác có tên Akka Dataflow http://doc.akka.io/docs/akka/2.3-M1/scala/dataflow.html sử dụng từ ngữ khác nhau nhưng về mặt khái niệm thì rất giống nhau, tuy nhiên được triển khai bằng cách sử dụng các phần tiếp theo được phân tách, không phải là macro (vì vậy nó hoạt động với các phiên bản Scala cũ hơn như 2.9).


1

Java không có tính năng tương đương trực tiếp với tính năng ngôn ngữ C # được gọi là async / await, tuy nhiên, có một cách tiếp cận khác cho vấn đề mà async / await đang cố gắng giải quyết. Nó được gọi là dự án Loom , sẽ cung cấp các luồng ảo cho đồng thời thông lượng cao. Nó sẽ có sẵn trong một số phiên bản tương lai của OpenJDK.

Cách tiếp cận này cũng giải quyết " vấn đề chức năng màu " mà async / await có.

Tính năng tương tự cũng có thể được tìm thấy trong Golang ( goroutines ).


0

Nếu bạn chỉ sau mã sạch mô phỏng hiệu ứng tương tự như async / await trong java và không ngại chặn luồng mà nó được gọi cho đến khi nó kết thúc, chẳng hạn như trong thử nghiệm, bạn có thể sử dụng mã như mã này:

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

Thư viện Java AsynHelper bao gồm một tập hợp các lớp / phương thức tiện ích cho các cuộc gọi không đồng bộ (và chờ).

Nếu muốn chạy một tập hợp các lệnh gọi phương thức hoặc khối mã không đồng bộ, thì nó bao gồm một phương thức trợ giúp hữu ích AsyncTask .submitT task như trong đoạn trích dưới đây.

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

Nếu muốn chờ cho đến khi tất cả các mã không đồng bộ được hoàn thành, thì có thể sử dụng biến AsyncTask.submitT taskAndWait.

Ngoài ra nếu đó là mong muốn có được một giá trị trả về từ mỗi lời gọi phương thức không đồng bộ hoặc khối mã, AsyncSupplier .submitSuppliers thể được sử dụng để kết quả có thể được thì thu được bằng cách từ mảng cung cấp kết quả trả về bởi phương pháp này. Dưới đây là đoạn mẫu:

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);

Nếu loại trả về của mỗi phương thức khác nhau, hãy sử dụng loại đoạn mã dưới đây.

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());

Kết quả của các lệnh gọi / khối mã không đồng bộ cũng có thể được lấy tại một điểm mã khác nhau trong cùng một luồng hoặc một luồng khác như trong đoạn mã dưới đây.

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());
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.