Apa perbedaan antara Future
dan Promise
?
Mereka berdua bertindak seperti pengganti untuk hasil masa depan, tetapi di mana perbedaan utama?
java
concurrency
future
promise
pengguna1170330
sumber
sumber
Promise
dan terserah Anda untuk menyimpannya. Ketika orang lain membuat Anda berjanji, Anda harus menunggu untuk melihat apakah mereka menghargainyaFuture
Jawaban:
Menurut diskusi ini ,
Promise
akhirnya telah dipanggilCompletableFuture
untuk dimasukkan dalam Java 8, dan javadoc-nya menjelaskan:Contoh juga diberikan dalam daftar:
Perhatikan bahwa API final sedikit berbeda tetapi memungkinkan eksekusi asinkron serupa:
sumber
(Aku tidak sepenuhnya senang dengan jawaban sejauh ini, jadi ini usahaku ...)
Saya pikir komentar Kevin Wright ( "Anda bisa membuat Janji dan itu terserah Anda untuk menyimpannya. Ketika orang lain membuat Anda berjanji, Anda harus menunggu untuk melihat apakah mereka menghormatinya di Masa Depan" ) merangkumnya dengan cukup baik, tetapi beberapa Penjelasan bisa bermanfaat.
Berjangka dan janji adalah konsep yang sangat mirip, perbedaannya adalah bahwa masa depan adalah wadah baca-saja untuk hasil yang belum ada, sementara janji dapat ditulis (biasanya hanya sekali). Java 8 CompletableFuture dan Guava SettableFuture dapat dianggap sebagai janji, karena nilainya dapat diatur ("selesai"), tetapi mereka juga mengimplementasikan antarmuka Masa Depan, oleh karena itu tidak ada perbedaan untuk klien.
Hasil masa depan akan ditetapkan oleh "orang lain" - oleh hasil perhitungan yang tidak sinkron. Perhatikan bagaimana FutureTask - masa depan klasik - harus diinisialisasi dengan Callable atau Runnable, tidak ada konstruktor tanpa argumen, dan FutureTask dan FutureTask keduanya hanya-baca dari luar (metode yang ditetapkan FutureTask dilindungi). Nilai akan ditetapkan ke hasil perhitungan dari dalam.
Di sisi lain, hasil dari janji dapat ditetapkan oleh "Anda" (atau bahkan oleh siapa saja) kapan saja karena memiliki metode setter publik. CompletableFuture dan SettableFuture dapat dibuat tanpa tugas apa pun, dan nilainya dapat diatur kapan saja. Anda mengirim janji ke kode klien, dan memenuhinya nanti seperti yang Anda inginkan.
Perhatikan bahwa CompletableFuture bukan janji "murni", ia dapat diinisialisasi dengan tugas seperti FutureTask, dan fitur yang paling berguna adalah rantai proses langkah yang tidak terkait.
Juga perhatikan bahwa janji tidak harus menjadi subtipe masa depan dan tidak harus menjadi objek yang sama. Dalam Scala, objek Masa Depan dibuat oleh perhitungan asinkron atau oleh objek Janji yang berbeda . Dalam C ++ situasinya mirip: objek janji digunakan oleh produsen dan objek masa depan oleh konsumen. Keuntungan dari pemisahan ini adalah bahwa klien tidak dapat menetapkan nilai masa depan.
Baik Spring dan EJB 3.1 memiliki kelas AsyncResult, yang mirip dengan janji Scala / C ++. AsyncResult tidak mengimplementasikan Future tetapi ini bukan masa depan yang sebenarnya: metode asynchronous di Spring / EJB mengembalikan objek Future yang berbeda dan hanya-baca melalui beberapa sihir latar belakang, dan masa depan "nyata" kedua ini dapat digunakan oleh klien untuk mengakses hasilnya.
sumber
Saya sadar bahwa sudah ada jawaban yang diterima tetapi ingin menambahkan dua sen saya:
TLDR: Masa Depan dan Janji adalah dua sisi dari operasi asinkron: konsumen / pemanggil vs. produsen / implementor .
Sebagai pemanggil metode API asinkron, Anda akan mendapatkan
Future
sebagai pegangan untuk hasil perhitungan. Anda dapat misalnya memanggilnyaget()
untuk menunggu perhitungannya selesai dan mengambil hasilnya.Sekarang pikirkan bagaimana metode API ini benar-benar diimplementasikan: Implementor harus
Future
segera mengembalikan . Mereka bertanggung jawab untuk menyelesaikan masa depan itu segera setelah perhitungan dilakukan (yang akan mereka ketahui karena menerapkan logika pengiriman ;-)). Mereka akan menggunakan aPromise
/CompletableFuture
untuk melakukan hal itu: Bangun dan kembalikanCompletableFuture
segera, dan panggilcomplete(T result)
setelah perhitungan selesai.sumber
Saya akan memberikan contoh tentang apa itu Janji dan bagaimana nilainya dapat ditetapkan kapan saja, berlawanan dengan Masa Depan, yang nilainya hanya dapat dibaca.
Misalkan Anda memiliki seorang ibu dan Anda meminta uang kepadanya.
Output dari itu adalah:
Janji Mom telah dibuat, tetapi menunggu beberapa acara "penyelesaian".
Anda membuat acara seperti itu, menerima janjinya dan mengumumkan rencana Anda untuk berterima kasih kepada ibumu:
Pada saat ini ibu mulai membuka dompetnya ... tetapi sangat lambat ...
dan ayah mencampuri lebih cepat dan menyelesaikan janjinya daripada ibumu:
Pernahkah Anda memperhatikan seorang eksekutor yang saya tulis secara eksplisit?
Menariknya, jika Anda menggunakan pelaksana implisit default sebagai gantinya (commonPool) dan ayah tidak ada di rumah, tetapi hanya ibu yang memiliki "dompet lambat", maka janjinya hanya akan selesai, jika program ini hidup lebih lama dari yang dibutuhkan ibu untuk mendapatkan uang dari tas.
Eksekutor default bertindak seperti "daemon" dan tidak menunggu semua janji dipenuhi. Saya belum menemukan deskripsi yang baik tentang fakta ini ...
sumber
Tidak yakin apakah ini bisa menjadi jawaban tetapi ketika saya melihat apa yang dikatakan orang lain untuk seseorang, mungkin Anda membutuhkan dua abstraksi terpisah untuk kedua konsep ini sehingga salah satunya (
Future
) hanya merupakan tampilan hanya baca dari yang lain (Promise
) ... tapi sebenarnya ini tidak diperlukan.Sebagai contoh, lihat bagaimana janji-janji didefinisikan dalam javascript:
https://promisesaplus.com/
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
Fokusnya adalah pada kompabilitas menggunakan
then
metode seperti:yang membuat perhitungan asinkron terlihat seperti sinkron:
yang cukup keren. (Tidak sekeren async-tunggu tapi async-tunggu hanya menghilangkan boilerplate .... lalu (fungsi (hasil) {.... darinya).
Dan sebenarnya abstraksi mereka cukup bagus sebagai konstruktor janji
memungkinkan Anda untuk memberikan dua panggilan balik yang dapat digunakan untuk menyelesaikan dengan
Promise
sukses atau dengan kesalahan. Sehingga hanya kode yang membuatPromise
bisa menyelesaikannya dan kode yang menerima objek yang sudah dibangunPromise
memiliki tampilan hanya baca.Dengan warisan hal di atas dapat dicapai jika tekad dan penolakan adalah metode yang dilindungi.
sumber
CompletableFuture
mungkin memiliki beberapa kesamaan denganPromise
tetapi itu tetap bukanPromise
, karena cara itu dimaksudkan untuk dikonsumsi berbeda:Promise
hasil a dikonsumsi oleh panggilanthen(function)
, dan fungsi dieksekusi dalam konteks produsen segera setelah produsen memanggilresolve
. Hasil AFuture
dikonsumsi dengan meneleponget
yang menyebabkan utas konsumen menunggu sampai utas produsen menghasilkan nilai, lalu memprosesnya di konsumen.Future
secara inheren multithreaded, tapi ...Promise
hanya dengan satu utas (dan pada kenyataannya itulah lingkungan yang sebenarnya mereka dirancang untuk: aplikasi javascript umumnya hanya memiliki satu utas, sehingga Anda tidak dapat menerapkannya diFuture
sana).Promise
Oleh karena itu jauh lebih ringan dan efisien daripadaFuture
, tetapiFuture
dapat membantu dalam situasi yang lebih kompleks dan membutuhkan kerjasama antara benang yang tidak dapat dengan mudah diatur dengan menggunakanPromise
s. Untuk meringkas:Promise
adalah model dorong, sementaraFuture
adalah model tarikan (lih Iterable vs Observable)XMLHttpRequest
). Saya tidak percaya klaim efisiensi, apakah Anda memiliki beberapa angka? +++ Konon, penjelasan yang sangat bagus.get
yang belum terselesaikanFuture
tentu akan melibatkan 2 sakelar konteks utas, yang setidaknya beberapa tahun lalu kemungkinan membutuhkan sekitar 50 kita .Untuk kode klien, Janji adalah untuk mengamati atau melampirkan panggilan balik ketika suatu hasil tersedia, sedangkan Masa Depan adalah untuk menunggu hasil dan kemudian melanjutkan. Secara teoritis apa pun yang mungkin dilakukan dengan masa depan apa yang dapat dilakukan dengan janji, tetapi karena perbedaan gaya, API yang dihasilkan untuk janji dalam berbagai bahasa membuat rantai lebih mudah.
sumber
Tidak ada metode yang ditetapkan di antarmuka Masa Depan, hanya dapatkan metode, jadi ini hanya baca. Tentang CompletableFuture, artikel ini mungkin membantu. masa depan yang dapat diselesaikan
sumber