Bagaimana saya harus memilih antara ExecutorService ini mengirimkan atau mengeksekusi , jika nilai yang dikembalikan adalah bukan urusan saya?
Jika saya menguji keduanya, saya tidak melihat perbedaan di antara keduanya kecuali nilai yang dikembalikan.
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.execute(new Task());
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
threadExecutor.submit(new Task());
sumber
Runnable
akan dibungkusTask
atau tidak, yang mungkin tidak Anda kendalikan. Misalnya, jika AndaExecutor
benar-benar seorangScheduledExecutorService
, tugas Anda secara internal akan dibungkusFuture
dan tidakThrowable
terikat akan terikat pada objek ini.Future
atau tidak', tentu saja. Lihat Javadoc untuk mengeksekusi ScheduledThreadPoolExecutor # , misalnya.mengeksekusi : Gunakan untuk api dan lupakan panggilan
kirim : Gunakan untuk memeriksa hasil pemanggilan metode dan mengambil tindakan yang sesuai pada
Future
keberatan yang dikembalikan oleh pemanggilanDari javadocs
submit(Callable<T> task)
Future<?> submit(Runnable task)
Anda harus berhati-hati saat menggunakan
submit()
. Itu menyembunyikan pengecualian dalam kerangka itu sendiri kecuali jika Anda menanamkan kode tugas Anda ditry{} catch{}
blok.Kode contoh: Kode ini tertelan
Arithmetic exception : / by zero
.keluaran:
Melemparkan kode yang sama dengan mengganti
submit()
denganexecute
():Menggantikan
dengan
keluaran:
Bagaimana menangani jenis skenario ini saat menggunakan kirim ()?
CustomThreadPoolExecutor
Solusi baru:
keluaran:
sumber
jika Anda tidak peduli dengan tipe pengembalian, gunakan eksekusi. itu sama dengan mengirimkan, hanya tanpa kembalinya Masa Depan.
sumber
Diambil dari Javadoc:
Secara pribadi saya lebih suka menggunakan eksekusi karena rasanya lebih deklaratif, meskipun ini benar-benar masalah preferensi pribadi.
Untuk memberikan informasi lebih lanjut: dalam hal
ExecutorService
implementasi, implementasi inti yang dikembalikan oleh panggilan keExecutors.newSingleThreadedExecutor()
adalah aThreadPoolExecutor
.The
submit
panggilan disediakan oleh induknyaAbstractExecutorService
dan semua panggilan mengeksekusi secara internal. mengeksekusi ditimpa / disediakan olehThreadPoolExecutor
langsung.sumber
Dari Javadoc :
Jadi tergantung pada implementasi
Executor
Anda mungkin menemukan bahwa thread mengirimkan blok saat tugas sedang dieksekusi.sumber
Jawaban lengkapnya adalah komposisi dari dua jawaban yang dipublikasikan di sini (ditambah sedikit "ekstra"):
execute
(karena id jenis pengembaliannyavoid
)execute
mengharapkanRunnable
sebentarsubmit
dapat mengambil argumen aRunnable
atau aCallable
(untuk info lebih lanjut tentang perbedaan antara keduanya - lihat di bawah).execute
melembungkan segala pengecualian yang tidak dicentang segera (tidak dapat membuang pengecualian yang diperiksa !!!), sementarasubmit
mengikat segala jenis pengecualian ke masa depan yang kembali sebagai hasilnya, dan hanya ketika Anda memanggilfuture.get()
pengecualian (terbungkus) yang akan dilempar. Throwable yang akan Anda dapatkan adalah instance dariExecutionException
dan jika Anda akan memanggil objek ini,getCause()
ia akan mengembalikan Throwable asli.Beberapa poin (terkait) lainnya:
submit
tidak memerlukan pengembalian hasil, Anda masih dapat menggunakanCallable<Void>
(alih-alih menggunakan aRunnable
).Singkatnya, ini adalah praktik yang lebih baik untuk digunakan
submit
denganCallable
(vs.execute
dengan aRunnable
). Dan saya akan mengutip dari "Java concurrency in practice" Oleh Brian Goetz:sumber
Hanya menambahkan jawaban yang diterima-
Sumber
sumber