Dalam aplikasi satu -utusan, ketika Anda memanggil metode, hasilnya akan dikembalikan hanya ketika perhitungan selesai.
Public String DownloadContents (URL URL) melempar ioException {trystream input = url.openstream ()) {return ioutils.tring (input, standardc harset url ("http://www.example.com");
DownloadContents () terlihat tidak berbahaya, tetapi perlu dilakukan untuk waktu yang lama. Pada saat yang sama, untuk mengurangi keterlambatan, selama hasil tunggu, Anda mungkin perlu menangani pekerjaan lain secara mandiri pada saat yang sama. Di masa lalu, Anda dapat memulai utas baru atau menunggu hasilnya (berbagi memori, kunci, tunggu buruk ()/notify () pasangan).
Melalui mode <T> di masa depan, itu akan menjadi jelas:
Public Static Future <String> startDownloading (url url) {// ...} final Future <pring> contentSfuture = startDownload (baru, http: //www.example .com ")); // konten string komputasi lain = contentSfuture .mendapatkan ();
Kami akan menyadari startdownloading (), startdownloading () tidak akan diblokir, tetapi menunggu situs eksternal untuk merespons. Sebaliknya, jika kembali dengan cepat dan mengembalikan objek <string> masa depan yang ringan. Objek ini adalah janji, jadi tipe string di masa depan tersedia. Dengan kata lain, masa depan adalah agen atau pengemasan objek, bukan objek target nyata. Setelah perhitungan asinkron selesai, Anda dapat mengekstraknya. Jadi antarmuka macam apa yang disediakan di masa depan?
Future.get () adalah metode yang paling penting. Ini memblokir dan menunggu sampai hasil janji tersedia, jadi jika kita benar -benar membutuhkan string ini, hubungi metode get () dan tunggu. Ada juga versi beban berat yang menerima parameter batas waktu.
Dalam beberapa kasus, Anda mungkin ingin secara diam -diam melihat apakah masa depan tersedia. Ini dapat dilakukan melalui isDone (). Bayangkan sebuah situasi, pengguna Anda sedang menunggu beberapa perhitungan yang tidak sinkron.
Final Future <string> contentSfuture = startDownloading (URL baru ("http://www.example.com"); while (! ContentSfuture.isdone ()) {askusertoWail (); do somecomputationinthemeantime ();} contentSfuture.get (); ;;
Akhirnya, konten Future.get () dijamin akan segera kembali tanpa diblokir, karena Future.isdone () mengembalikan true. Jika Anda mengikuti model ini, Anda tidak akan sibuk menunggu dan menelepon isDone () secara bergantian setiap detik.
Membatalkan Futrues adalah yang terakhir yang belum kami bahas. Bayangkan Anda memulai pekerjaan asinkron dan Anda hanya bisa menunggu beberapa waktu. Namun, Anda adalah warga negara yang baik, Anda harus memberi tahu objek masa depan ini: Saya tidak membutuhkan Anda lagi, Anda tidak peduli. Kemudian Anda dapat menghemat sumber daya dengan menghentikan tugas yang sudah ketinggalan zaman. Tata bahasa sederhana:
ContentSfuture.cancel (true);
Kita semua suka menyembunyikan, parameter tipe boer, bukan? Pembatalan dapat diimplementasikan melalui dua cara: sebelum tugas dimulai, parameter palsu dibatalkan, asalkan sebelum hasil masa depan yang diungkapkan, perhitungan dimulai. Setelah Callable.call () berjalan menjadi setengah, maka kami ingin membiarkannya berakhir. Apakah menurut Anda ini bagus? Fenomena mereka yang muntah interupsi exception, metode terkenal, seperti thread.sleep (), objek.Wait (), conition.aWait (), dll. Bahkan jika Anda diblokir dalam metode ini dan beberapa orang memutuskan untuk membatalkan panggilan Anda , mereka tidak diragukan lagi akan melempar Exception Interruption, dan mengirim seseorang untuk mengganggu tugas operasi saat ini.
Jadi kami sekarang memahami apa yang akan terjadi di masa depan --- penampung, Anda bisa mendapatkan objek target di masa depan. Sama seperti mobil, tidak ada kunci untuk diproduksi. Tetapi bagaimana Anda bisa mendapatkan contoh masa depan dalam aplikasi? Dua sumber daya yang paling umum adalah kumpulan utas dan metode asinkron (dukungan kumpulan utas). Oleh karena itu, metode startDownloading () dapat ditulis ulang sebagai:
Private final executorservice pool = executors.newfixedThreadpool (10); InputStream input = url.openstream ()) {return ioutils.toString (input, standardcharsets.utf_8);}});}
Meskipun ada banyak masalah tata bahasa yang membosankan, pemikiran dasarnya sederhana: komputasi pengemasan yang perlu dijalankan untuk waktu yang lama dikemas ke <string> yang dapat disesuaikan, dan kirim () ke kumpulan utas. utas. Setelah mengirimkan, implementasi Future <string> seperti menautkan ke tugas dan kumpulan utas Anda dengan cara tertentu. Jelas tugas Anda tidak akan segera dieksekusi. Tugas tinggal di tengah juga dapat membatalkan tugas yang telah lama berjalan, tetapi ini adalah hal yang lebih rumit.
Anda juga dapat bertemu Future di Spring dan EJB. Misalnya, Anda dapat menambahkan anotasi @Async ke kerangka musim semi:
@AsyncPublic Future <string> startDownloading (URL URL akhir) melempar ioException {try (inputStream input = url.openstream ()) {return asyncres baru ult <> (ioutils.toString (input, standardcharsets.utf_8));}}}
Perhatikan bahwa kami cukup mengimplementasikan masa depan melalui hasil pengemasan ke AsyncResult, tetapi metode ini sendiri tidak akan berinteraksi dengan kumpulan utas atau diproses asinkron. Musim semi nanti akan mewakili semua panggilan ke startdownloading () dan dijalankan di kumpulan utas. Di EJB, fitur yang sama selesai dengan menambahkan @AsynChronoUsAnnotation.