Java - CompletableFuture API Cải Tiến
Xin chào các nhà phát triển Java tương lai! Tôi rất phấn khích để bắt đầu hành trình thú vị này cùng các bạn khi chúng ta khám phá thế giới tuyệt vời của các cải tiến trong API CompletableFuture của Java. Đừng lo lắng nếu bạn mới bắt đầu học lập trình; chúng ta sẽ bắt đầu từ những điều cơ bản và dần dần nâng cao. Cuối cùng của bài hướng dẫn này, bạn sẽ ngạc nhiên về những gì bạn đã học được!
CompletableFuture Là Gì?
Trước khi chúng ta đi sâu vào các cải tiến, hãy hiểu CompletableFuture là gì. Hãy tưởng tượng bạn đang nấu một bữa ăn phức tạp. Bạn không muốn chờ đợi mì chín trước khi bạn bắt đầu băm rau, phải không? CompletableFuture giống như việc bạn có nhiều đầu bếp trong nhà bếp của mình, mỗi người thực hiện một nhiệm vụ khác nhau đồng thời. Đây là cách Java xử lý lập trình không đồng bộ, cho phép mã của bạn thực hiện nhiều việc cùng một lúc mà không bị rối loạn.
Ví Dụ Cơ Bản về CompletableFuture
Hãy bắt đầu với một ví dụ đơn giản:
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Hello, Future!";
});
System.out.println(future.get());
Trong đoạn mã này, chúng ta đang tạo một CompletableFuture sẽ trả về một chuỗi String. Phương thức supplyAsync
chạy mã của chúng ta trong một luồng khác. Chúng ta đang mô phỏng một công việc bằng cách làm cho luồng đó ngủ trong một giây. Sau đó, nó trả về lời chào của chúng ta. Phương thức get()
chờ đợi future hoàn thành và cho chúng ta kết quả.
Hỗ Trợ Tốt Hơn Cho Độ Trễ và Hạn Giờ
Một trong những cải tiến thú vị trong API CompletableFuture là hỗ trợ tốt hơn cho độ trễ và hạn giờ. Điều này giống như việc bạn đặt một计时器 trong nhà bếp - bạn không muốn nước sốt của bạn đun sôi mãi mãi!
Ví Dụ Độ Trễ
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + ", World!")
.completeOnTimeout("Timeout occurred", 2, TimeUnit.SECONDS)
.orTimeout(3, TimeUnit.SECONDS);
System.out.println(future.get());
Trong ví dụ này, chúng ta đang tạo một future nói "Hello", sau đó thay đổi nó thành "Hello, World!". Chúng ta sử dụng hai phương thức mới:
-
completeOnTimeout
: Điều này sẽ hoàn thành future với một giá trị mặc định nếu nó không hoàn thành trong 2 giây. -
orTimeout
: Điều này sẽ ném một ngoại lệ nếu future không hoàn thành trong 3 giây.
Bằng cách này, chúng ta đảm bảo rằng mã của chúng ta không bị treo nếu có điều gì đó xảy ra sai.
Hỗ Trợ Tốt Hơn Cho Việc Phụ Thể
Lớp CompletableFuture bây giờ dễ dàng mở rộng hơn, cho phép bạn tạo ra các phiên bản chuyên dụng của riêng mình. Điều này giống như việc bạn có thể tạo ra một thiết bị nhà bếp tùy chỉnh làm chính xác những gì bạn cần!
Ví Dụ Phụ Thể
public class MyFuture<T> extends CompletableFuture<T> {
@Override
public <U> MyFuture<U> thenApply(Function<? super T, ? extends U> fn) {
return (MyFuture<U>) super.thenApply(fn);
}
// Các phương thức khác đã bị覆盖...
}
MyFuture<String> myFuture = new MyFuture<>();
myFuture.complete("Hello, Custom Future!");
System.out.println(myFuture.get());
Trong ví dụ này, chúng ta đang tạo một lớp MyFuture
mà mở rộng CompletableFuture
. Chúng ta đang覆盖 phương thức thenApply
để trả về loại future tùy chỉnh của chúng ta. Điều này cho phép chúng ta nối các thao tác trong khi giữ lại loại tùy chỉnh của chúng ta.
Các Phương Thức Nhà Máy Mới
Java đã giới thiệu các phương thức nhà máy mới để làm cho việc tạo ra CompletableFutures dễ dàng hơn. Điều này giống như việc bạn có các công thức预设 trong sách nấu ăn của mình!
Bảng Các Phương Thức Nhà Máy
Phương Thức | Mô Tả |
---|---|
failedFuture(Throwable ex) | Tạo một CompletableFuture đã hoàn thành ngoại lệ |
completedStage(T value) | Tạo một CompletionStage đã hoàn thành với giá trị cho trước |
failedStage(Throwable ex) | Tạo một CompletionStage đã hoàn thành ngoại lệ |
Ví Dụ Phương Thức Nhà Máy
CompletableFuture<String> successFuture = CompletableFuture.completedFuture("Success!");
CompletableFuture<String> failedFuture = CompletableFuture.failedFuture(new Exception("Oops!"));
try {
System.out.println(successFuture.get());
System.out.println(failedFuture.get());
} catch (Exception e) {
System.out.println("An error occurred: " + e.getMessage());
}
Trong ví dụ này, chúng ta đang sử dụng phương thức completedFuture
để tạo một future đã thành công và phương thức failedFuture
để tạo một future đã thất bại. Điều này có thể hữu ích cho việc kiểm tra hoặc khi bạn cần tích hợp mã đồng bộ và mã không đồng bộ.
Kết Luận
Wow! Chúng ta đã bao quát rất nhiều nội dung hôm nay. Từ việc hiểu cơ bản về CompletableFuture đến việc khám phá các cải tiến mới, bạn đã bước những bước đầu tiên vào thế giới lập trình không đồng bộ trong Java. Nhớ rằng, giống như việc học nấu ăn, việc thành thạo các khái niệm này đòi hỏi sự thực hành. Đừng sợ thử nghiệm và mắc lỗi - đó là cách chúng ta học hỏi!
Trong những năm dạy học của tôi, tôi đã thấy rằng những học sinh xuất sắc là những người không害怕 làm脏双手 với mã. Vì vậy, tôi khuyến khích bạn lấy các ví dụ này, sửa đổi chúng, làm chúng bị vỡ và xem会发生什么. Đó là cách tốt nhất để thực sự hiểu cách chúng hoạt động.
Khi chúng ta kết thúc, tôi nhớ lại một học sinh曾经说过 rằng việc học CompletableFuture giống như việc học chơi cào cào - ban đầu, nó có vẻ không thể giữ tất cả các quả bóng trong không trung, nhưng với sự thực hành, nó trở thành bản năng tự nhiên. Vậy hãy tiếp tục thực hành, và trước khi bạn biết điều đó, bạn sẽ thành thạo việc xử lý các thao tác không đồng bộ phức tạp như một chuyên gia!
Chúc các bạn may mắn trong việc lập trình, các nhà mã hóa Java tương lai!
Credits: Image by storyset