Saya telah melihat goroutine Go akhir-akhir ini dan berpikir akan menyenangkan memiliki sesuatu yang serupa di Java. Sejauh saya telah mencari cara umum untuk memparalelkan pemanggilan metode adalah dengan melakukan sesuatu seperti:
final String x = "somethingelse";
new Thread(new Runnable() {
public void run() {
x.matches("something");
}
}).start();
Itu tidak terlalu elegan. Apakah ada cara yang lebih baik untuk melakukan ini? Saya membutuhkan solusi seperti itu dalam sebuah proyek jadi saya memutuskan untuk mengimplementasikan kelas pembungkus saya sendiri di sekitar pemanggilan metode async.
Saya menerbitkan kelas pembungkus saya di J-Go . Tapi saya tidak tahu apakah ini solusi yang bagus. Penggunaannya sederhana:
SampleClass obj = ...
FutureResult<Integer> res = ...
Go go = new Go(obj);
go.callLater(res, "intReturningMethod", 10); //10 is a Integer method parameter
//... Do something else
//...
System.out.println("Result: "+res.get()); //Blocks until intReturningMethod returns
atau kurang bertele-tele:
Go.with(obj).callLater("myRandomMethod");
//... Go away
if (Go.lastResult().isReady()) //Blocks until myRandomMethod has ended
System.out.println("Method is finished!");
Secara internal, saya menggunakan kelas yang mengimplementasikan Runnable dan melakukan beberapa pekerjaan Refleksi untuk mendapatkan objek metode yang benar dan menjalankannya.
Saya ingin pendapat tentang perpustakaan kecil saya dan tentang masalah membuat panggilan metode asinkron seperti ini di Java. Apakah ini aman? Apakah sudah ada cara yang lebih sederhana?
sumber
Jawaban:
Saya baru saja menemukan bahwa ada cara yang lebih bersih untuk melakukan Anda
(Setidaknya di Java 8), Anda dapat menggunakan ekspresi lambda untuk mempersingkatnya menjadi:
Sesederhana membuat fungsi di JS!
sumber
Java 8 memperkenalkan CompletableFuture yang tersedia dalam paket java.util.concurrent.CompletableFuture, dapat digunakan untuk membuat panggilan asynch:
sumber
CompletableFuture
disebutkan dalam jawaban lain, tetapi jawaban itu menggunakan seluruhsupplyAsync(...)
rantai. Ini adalah pembungkus sederhana yang cocok dengan pertanyaan dengan sempurna.ForkJoinPool.commonPool().execute()
memiliki overhead yang sedikit lebih sedikitAnda mungkin juga ingin mempertimbangkan kelas tersebut
java.util.concurrent.FutureTask
.Jika Anda menggunakan Java 5 atau yang lebih baru, FutureTask adalah implementasi siap pakai dari "Komputasi asinkron yang dapat dibatalkan".
Bahkan ada lebih banyak perilaku penjadwalan eksekusi asinkron yang tersedia dalam
java.util.concurrent
paket (misalnya,ScheduledExecutorService
), tetapiFutureTask
mungkin memiliki semua fungsionalitas yang Anda butuhkan.Saya bahkan akan melangkah lebih jauh dengan mengatakan bahwa tidak lagi disarankan untuk menggunakan pola kode pertama yang Anda berikan sebagai contoh sejak
FutureTask
tersedia. (Dengan asumsi Anda menggunakan Java 5 atau lebih baru.)sumber
saya tidak suka ide menggunakan Refleksi untuk itu.
Tidak hanya berbahaya jika terlewat di beberapa refactoring, tapi juga bisa diingkari
SecurityManager
.FutureTask
adalah opsi yang bagus sebagai opsi lain dari paket java.util.concurrent.Favorit saya untuk tugas-tugas sederhana:
sedikit lebih pendek daripada membuat Thread (tugas adalah Callable atau Runnable)
sumber
ExecutorService
instance, sehingga Anda dapat meneleponshutdown()
saat diperlukan.Anda dapat menggunakan sintaks Java8 untuk CompletableFuture, dengan cara ini Anda dapat melakukan komputasi asinkron tambahan berdasarkan hasil dari pemanggilan fungsi asinkron.
sebagai contoh:
Rincian lebih lanjut dapat ditemukan di artikel ini
sumber
Anda dapat menggunakan
@Async
anotasi dari jcabi-aspect dan AspectJ:Saat Anda memanggil
save()
, utas baru dimulai dan menjalankan tubuhnya. Untaian utama Anda berlanjut tanpa menunggu hasilsave()
.sumber
Anda dapat menggunakan Future-AsyncResult untuk ini.
Referensi: https://spring.io/guides/gs/async-method/
sumber
Java juga menyediakan cara yang bagus untuk memanggil metode async. di java.util.concurrent kami memiliki ExecutorService yang membantu dalam melakukan hal yang sama. Inisialisasi objek Anda seperti ini -
dan kemudian memanggil fungsi seperti-
sumber
Ini mungkin bukan solusi nyata, tetapi sekarang - di Java 8 - Anda dapat membuat kode ini terlihat setidaknya sedikit lebih baik menggunakan ekspresi lambda.
Dan Anda bahkan dapat melakukan ini dalam satu baris, tetap membuatnya cukup mudah dibaca.
sumber
Anda dapat menggunakan
AsyncFunc
dari Cactoos :Ini akan dijalankan di latar belakang dan hasilnya akan tersedia dalam
get()
formatFuture
.sumber
Ini tidak benar-benar terkait tetapi jika saya memanggil metode secara asinkron misalnya match (), saya akan menggunakan:
Kemudian untuk memanggil metode asynchronous saya akan menggunakan:
Saya telah menguji ini dan berhasil. Hanya berpikir itu dapat membantu orang lain jika mereka datang untuk "metode asynchronous".
sumber
Ada juga perpustakaan bagus untuk Async-Await yang dibuat oleh EA: https://github.com/electronicarts/ea-async
Dari Readme mereka:
Dengan EA Async
Tanpa EA Async
sumber