2013-06-22 26 views
16

Tôi đang cố gắng triển khai tác vụ @Async mùa xuân có kiểu trả về Tương lai, nhưng tôi không thể tìm ra cách thực hiện đúng cách.Spring 3.2 @Async nhiệm vụ với kiểu trả về tương lai

  1. Tôi sẽ đạt được điều gì bằng cách làm như vậy? liệu bây giờ tôi có thể kiểm soát công việc của mình để tôi có thể dừng nó và chạy nó không?
  2. Có bất kỳ triển khai tham chiếu nào về cách tôi có thể thực hiện không? lò xo không cung cấp bất kỳ.

EDIT

Từ nguồn mùa xuân và mùa xuân refrence dẫn sử dụng:

Ngay cả phương pháp mà trả về một giá trị có thể được gọi không đồng bộ. Tuy nhiên, các phương thức như vậy được yêu cầu để có giá trị trả lại được nhập trong tương lai. Điều này vẫn mang lại lợi ích của việc thực hiện không đồng bộ để người gọi có thể thực hiện các tác vụ khác trước khi gọi get() vào tương lai đó.

và nó mang lại cho một ví dụ như vậy:

@Async 
Future<String> returnSomething(int i) { 
// this will be executed asynchronously 
} 

Làm thế nào để thực hiện điều này một cách chính xác?

Trả lời

21

Check-out this blog post.

Sử dụng @Async cho phép bạn chạy tính toán theo phương thức không đồng bộ. Điều này có nghĩa rằng nếu nó được gọi (trên một bean được quản lý Spring), điều khiển được trả về ngay lập tức cho người gọi và mã trong phương thức được chạy trong một luồng khác. Người gọi nhận được một đối tượng Future được ràng buộc với tính toán đang chạy và có thể sử dụng nó để kiểm tra xem việc tính toán có đang chạy hay không và chờ kết quả.

Tạo phương thức như vậy thật đơn giản. Chú thích nó với @Async và bọc kết quả trong AsyncResult, như được hiển thị trong bài đăng trên blog.

+1

Đó là những gì tôi đang tìm kiếm – engma

+0

vì vậy điều này có nghĩa là tôi có thể ngừng nhiệm vụ của tôi bất cứ lúc nào nếu nó chưa bị hủy phải không? – engma

+3

@ Developer106 Có, bạn có thể _interrupt_ phương thức không đồng bộ của bạn bằng cách gọi [cancel (true)] (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html#cancel (boolean)) trên 'Tương lai' được trả về. Nhưng sự gián đoạn không hoạt động tự động. Hoặc là phương thức nên kiểm tra gián đoạn bằng cách gọi 'Thread.isInterrupted()' hoặc sử dụng các phương thức ném 'InterruptedException'. Xem [Ngắt] (http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html) trong Hướng dẫn Java. –

2

ExecutorService có thể lập lịch Gọi và trả về một đối tượng Tương lai. Tương lai là trình giữ chỗ chứa kết quả khi có sẵn. Nó cho phép bạn kiểm tra xem kết quả là có, hủy bỏ nhiệm vụ, hoặc chặn và chờ kết quả. Tương lai chỉ hữu ích khi bạn đang mong đợi một số đối tượng/giá trị từ nhiệm vụ.

cách chính xác để thực hiện cuộc gọi trong tương lai là:

Future<Integer> futureEvenNumber = executorService.submit(new NextEvenNumberFinder(10000)); 

// Do something. 

try { 
    Integer nextEvenNumber = futureEvenNumber.get(); 
} catch (ExecutionException e) { 
    System.err.println("NextEvenNumberFinder threw exception: " + e.getCause()); 
} 

Lớp NextEvenNumberFinder:

public class NextEvenNumberFinder implements Callable<Integer> { 
private int number; 

public NextEvenNumberFinder(int number) { this.number = number; } 

@Override 
public Integer call() throws Exception { 
    for (;;) 
     if (isEvenNumber(++number)) return number; 
} 

}

Xuân Tích hợp Reference Manual: http://static.springsource.org/spring-integration/reference/htmlsingle/

+0

Tôi sẽ cập nhật câu trả lời của mình để bạn có thể hiểu ý tôi là gì – engma

2

Check-out blog post

cấu hình quan trọng này là:

  1. @Async vào mùa xuân quản lý phương pháp đậu
  2. Enable async vào mùa xuân cấu hình xml bằng cách định nghĩa:

    <!-- Enables the detection of @Async and @Scheduled annotations on any Spring-managed object. --> 
         <task:annotation-driven/> 
    

    SimpleAsyncTaskExecutor sẽ được sử dụng theo mặc định.

Bó phản ứng trong một tương lai <> đối tượng

Ví dụ:

@Async 
    public Future<PublishAndReturnDocumentResult> generateDocument(FooBarBean bean) { 
//do some logic 
return new AsyncResult<PublishAndReturnDocumentResult>(result); 


} 

Sau đó bạn có thể kiểm tra nếu kết quả được thực hiện (result.isDone()) hoặc chờ đợi để có được phản hồi result.get()

Các vấn đề liên quan