Perbaikan API CompletableFuture Java 9

1. Perkenalan

Java 9 hadir dengan beberapa perubahan pada kelas CompletableFuture . Perubahan tersebut diperkenalkan sebagai bagian dari JEP 266 untuk menangani keluhan dan saran umum sejak diperkenalkan di JDK 8, lebih khusus lagi, dukungan untuk penundaan dan batas waktu, dukungan yang lebih baik untuk subclassing dan beberapa metode utilitas.

Dari segi kode, API hadir dengan delapan metode baru dan lima metode statis baru. Untuk mengaktifkan penambahan tersebut, kira-kira, 1500 dari 2400 baris kode diubah (sesuai Open JDK).

2. Penambahan API Instance

Seperti yang disebutkan, API instance hadir dengan delapan tambahan baru, yaitu:

  1. Pelaksana defaultExecutor ()
  2. CompletableFuture newIncompleteFuture ()
  3. Salinan CompletableFuture ()
  4. CompletionStage minimalCompletionStage ()
  5. CompletableFuture completeAsync (Pemasok pemasok, pelaksana pelaksana)
  6. CompletableFuture completeAsync (Pemasok pemasok)
  7. CompletableFuture orTimeout (waktu tunggu lama, unit TimeUnit)
  8. CompletableFuture completeOnTimeout (nilai T, long timeout, unit TimeUnit)

2.1. Metode defaultExecutor ()

Tanda tangan : Executor defaultExecutor ()

Mengembalikan Pelaksana default yang digunakan untuk metode asinkron yang tidak menetapkan Pelaksana .

new CompletableFuture().defaultExecutor()

Ini bisa diganti dengan subclass yang mengembalikan eksekutor yang menyediakan, setidaknya, satu utas independen.

2.2. Metode newIncompleteFuture ()

Tanda tangan : CompletableFuture newIncompleteFuture ()

The newIncompleteFuture , juga dikenal sebagai “konstruktor virtual”, digunakan untuk mendapatkan contoh masa depan completable baru dari jenis yang sama.

new CompletableFuture().newIncompleteFuture()

Metode ini sangat berguna saat membuat subclass CompletableFuture , terutama karena digunakan secara internal di hampir semua metode yang mengembalikan CompletionStage baru , yang memungkinkan subclass untuk mengontrol subclass apa yang dikembalikan oleh metode tersebut.

2.3. Metode copy ()

Tanda tangan : salinan CompletableFuture ()

Metode ini mengembalikan CompletableFuture baru yang:

  • Ketika ini diselesaikan secara normal, yang baru diselesaikan secara normal juga
  • Saat ini diselesaikan secara luar biasa dengan pengecualian X, yang baru juga diselesaikan secara luar biasa dengan CompletionException dengan X sebagai penyebabnya
new CompletableFuture().copy()

Metode ini mungkin berguna sebagai bentuk "penyalinan defensif", untuk mencegah klien menyelesaikan, sambil tetap dapat mengatur tindakan bergantung pada contoh tertentu dari CompletableFuture .

2.4. Metode minimalCompletionStage ()

Tanda tangan : CompletionStage minimalCompletionStage ()

Metode ini mengembalikan CompletionStage baru yang berperilaku persis sama seperti yang dijelaskan oleh metode salin, namun, instance baru tersebut melontarkan UnsupportedOperationException dalam setiap upaya untuk mengambil atau menyetel nilai yang diselesaikan.

new CompletableFuture().minimalCompletionStage()

CompletableFuture baru dengan semua metode yang tersedia dapat diambil dengan menggunakan metode toCompletableFuture yang tersedia di CompletionStage API.

2.5. Metode completeAsync ()

The completeAsync metode harus digunakan untuk menyelesaikan CompletableFuture asynchronous menggunakan nilai yang diberikan oleh Pemasok disediakan.

Tanda tangan :

CompletableFuture completeAsync(Supplier supplier, Executor executor) CompletableFuture completeAsync(Supplier supplier)

Perbedaan antara dua metode kelebihan beban ini adalah adanya argumen kedua, di mana Pelaksana yang menjalankan tugas dapat ditentukan. Jika tidak ada yang disediakan, eksekutor default (dikembalikan dengan metode defaultExecutor ) akan digunakan.

2.6. Metode orTimeout ()

Tanda tangan : CompletableFuture orTimeout (waktu tunggu lama, unit TimeUnit)

new CompletableFuture().orTimeout(1, TimeUnit.SECONDS)

Menyelesaikan CompletableFuture secara luar biasa dengan TimeoutException , kecuali jika diselesaikan sebelum waktu tunggu yang ditentukan.

2.7. Metode completeOnTimeout ()

Tanda tangan : CompletableFuture completeOnTimeout (nilai T, long timeout, unit TimeUnit)

new CompletableFuture().completeOnTimeout(value, 1, TimeUnit.SECONDS)

Menyelesaikan CompletableFuture secara normal dengan nilai yang ditentukan kecuali diselesaikan sebelum batas waktu yang ditentukan.

3. Penambahan API Statis

Beberapa metode utilitas juga ditambahkan. Mereka:

  1. Executor delayExecutor (delay lama, unit TimeUnit, Executor executor)
  2. Executor delayExecutor (delay lama, unit TimeUnit)
  3. CompletionStage completedStage(U value)
  4. CompletionStage failedStage(Throwable ex)
  5. CompletableFuture failedFuture(Throwable ex)

3.1. Methods delayedExecutor

Signatures:

Executor delayedExecutor(long delay, TimeUnit unit, Executor executor) Executor delayedExecutor(long delay, TimeUnit unit)

Returns a new Executor that submits a task to the given base executor after the given delay (or no delay if non-positive). Each delay commences upon invocation of the returned executor's execute method. If no executor is specified the default executor (ForkJoinPool.commonPool()) will be used.

3.2. Methods completedStage and failedStage

Signatures:

 CompletionStage completedStage(U value)  CompletionStage failedStage(Throwable ex)

This utility methods return already resolved CompletionStage instances, either completed normally with a value (completedStage) or completed exceptionally (failedStage) with the given exception.

3.3. Method failedFuture

Signature: CompletableFuture failedFuture(Throwable ex)

The failedFuture method adds the ability to specify an already completed exceptionally CompleatebleFuture instance.

4. Example Use Cases

Within this section, one will show some examples on how to use some of the new API.

4.1. Delay

This example will show how to delay the completion of a CompletableFuture with a specific value by one second. That can be achieved by using the completeAsync method together with the delayedExecutor.

CompletableFuture future = new CompletableFuture(); future.completeAsync(() -> input, CompletableFuture.delayedExecutor(1, TimeUnit.SECONDS));

4.2. Complete With Value on Timeout

Another way to achieve a delayed result is to use the completeOnTimeout method. This example defines a CompletableFuture that will be resolved with a given input if it stays unresolved after 1 second.

CompletableFuture future = new CompletableFuture(); future.completeOnTimeout(input, 1, TimeUnit.SECONDS);

4.3. Timeout

Another possibility is timing out which resolves the future exceptionally with TimeoutException. For example, having the CompletableFuture timing out after 1 second given it is not completed before that.

CompletableFuture future = new CompletableFuture(); future.orTimeout(1, TimeUnit.SECONDS);

5. Conclusion

Kesimpulannya, Java 9 hadir dengan beberapa tambahan pada CompletableFuture API, sekarang memiliki dukungan yang lebih baik untuk subclassing, berkat konstruktor virtual baruIncompleteFuture , dimungkinkan untuk mengambil kendali atas contoh CompletionStage yang dikembalikan di sebagian besar API CompletionStage .

Ini pasti memiliki dukungan yang lebih baik untuk penundaan dan batas waktu seperti yang ditunjukkan sebelumnya. Metode utilitas yang ditambahkan mengikuti pola yang masuk akal, memberikan CompletableFuture cara yang nyaman untuk menentukan instance yang diselesaikan.

Contoh yang digunakan dalam artikel ini dapat ditemukan di repositori GitHub kami.