Antarmuka Callable mirip dengan Runnable, di mana keduanya dirancang untuk kelas yang instansnya berpotensi dieksekusi oleh utas lainnya. Namun, Runnable tidak mengembalikan hasil dan tidak bisa melempar pengecualian yang dicentang.
Apa perlunya memiliki keduanya jika Callabledapat melakukan semua yang Runnabledilakukannya?
Karena Runnableantarmuka tidak dapat melakukan semua yang Callabledilakukannya!
Runnabletelah ada sejak Java 1.0, tetapi Callablehanya diperkenalkan di Java 1.5 ... untuk menangani kasus penggunaan yang Runnabletidak mendukung. Secara teori, tim Java bisa saja mengubah tanda tangan Runnable.run()metode ini, tetapi ini akan merusak kompatibilitas biner dengan kode pra-1.5, yang membutuhkan pengodean ulang saat memigrasi kode Java lama ke JVM yang lebih baru. Itu adalah TIDAK-TIDAK-yang-BESAR. Java berusaha keras untuk kompatibel ke belakang ... dan itu menjadi salah satu nilai jual terbesar Java untuk komputasi bisnis.
Dan, jelas, ada kasus penggunaan di mana tugas tidak perlu mengembalikan hasil atau melemparkan pengecualian yang diperiksa. Untuk kasus penggunaan Runnabletersebut , menggunakan lebih ringkas daripada menggunakan Callable<Void>dan mengembalikan nilai dummy ( null) dari call()metode.
Saya ingin tahu dari mana Anda mendapatkan sejarah ini. Ini sangat berguna.
spiderman
4
@prash - fakta dasar dapat ditemukan di buku teks lama. Seperti edisi pertama Java in a Nutshell.
Stephen C
4
(@prash - Juga ... dengan mulai menggunakan Java di era Java 1.1.)
Stephen C
1
@StephenC Jika saya membaca jawaban Anda dengan benar, Anda menyarankan Runnableada (sebagian besar) untuk alasan kompatibilitas ke belakang. Tapi bukankah ada situasi di mana tidak perlu atau terlalu mahal untuk mengimplementasikan (atau membutuhkan) Callableantarmuka (misalnya, dalam ScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit))? Jadi bukankah ada manfaat untuk mempertahankan kedua antarmuka dalam bahasa bahkan sejarah tidak memaksa hasil saat ini?
maks
1
@ Max - Yah saya mengatakan itu, dan saya masih setuju dengan itu. Namun, itu adalah alasan kedua. Namun demikian, saya menduga itu Runnableakan dimodifikasi jika tidak ada keharusan untuk menjaga kompatibilitas. The "boilerplate" return null;adalah argumen yang lemah. (Setidaknya, itu akan menjadi keputusan saya ... dalam konteks hipotetis di mana Anda dapat mengabaikan kompatibilitas ke belakang.)
Stephen C
82
Sebuah Callableperlu menerapkan call()metode sementara Runnablekebutuhan untuk menerapkan run()metode.
A Callabledapat mengembalikan nilai tetapi Runnabletidak bisa.
A Callabledapat membuang pengecekan yang dicek tetapi Runnabletidak bisa.
A Callabledapat digunakan dengan ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)metode tetapi Runnabletidak bisa.
publicinterfaceRunnable{void run();}publicinterfaceCallable<V>{
V call()throwsException;}
ExecutorService.submit (tugas Runnable) juga ada dan sangat berguna
Yair Kukielka
Runnable juga dapat digunakan dengan ExecutorService dengan mengikuti cara- 1) ExecutorService.execute (Runnable) 2) ExecutorService.submit (Runnable)
Azam Khan
2
Juga ada Executor.submit (tugas Callable <T>) tetapi Anda tidak dapat memanggilAll atau invokeAny dengan koleksi Koleksi tugas Runnable <? extends Callable <T>> task
nikli
36
Saya menemukan ini di blog lain yang dapat menjelaskan sedikit lebih banyak perbedaan ini :
Meskipun kedua antarmuka diimplementasikan oleh kelas-kelas yang ingin dieksekusi di utas eksekusi yang berbeda, tetapi ada beberapa perbedaan antara dua antarmuka yaitu:
Sebuah Callable<V>instance mengembalikan hasil dari tipe V, sedangkan Runnableinstance tidak.
Sebuah Callable<V>instance dapat membuang pengecualian yang diperiksa, sedangkan sebuah Runnableinstance tidak bisa
Para perancang Java merasa perlu memperluas kemampuan Runnableantarmuka, tetapi mereka tidak ingin memengaruhi penggunaan Runnableantarmuka dan mungkin itulah alasan mengapa mereka menggunakan antarmuka terpisah bernama CallableJava 1.5 daripada mengubah yang sudah ada. yang ada Runnable.
Mari kita lihat di mana orang akan menggunakan Runnable dan Callable.
Runnable dan Callable keduanya berjalan pada utas yang berbeda dari utas panggilan. Tetapi Callable dapat mengembalikan nilai dan Runnable tidak bisa. Jadi di mana ini benar-benar berlaku.
Runnable : Jika Anda memiliki tugas kebakaran dan lupa kemudian gunakan Runnable. Masukkan kode Anda di dalam Runnable dan ketika metode run () dipanggil, Anda dapat melakukan tugas Anda. Utas panggilan benar-benar tidak peduli ketika Anda melakukan tugas Anda.
Callable : Jika Anda mencoba mengambil nilai dari suatu tugas, maka gunakan Callable. Sekarang callable sendiri tidak akan melakukan pekerjaan itu. Anda akan membutuhkan Masa Depan yang dapat Anda gunakan untuk Callable Anda dan dapatkan nilai-nilai Anda di future.get (). Di sini utas panggilan akan diblokir sampai Masa Depan kembali dengan hasil yang pada gilirannya menunggu metode panggilan Callable () untuk dieksekusi.
Jadi pikirkan sebuah antarmuka ke kelas target di mana Anda memiliki metode terbungkus Runnable dan Callable. Kelas panggilan akan memanggil metode antarmuka Anda secara acak tanpa mengetahui Runnable dan yang Callable. Metode Runnable akan mengeksekusi secara tidak sinkron, sampai metode Callable dipanggil. Di sini utas kelas panggilan akan diblokir karena Anda mengambil nilai dari kelas target Anda.
CATATAN: Di dalam kelas target Anda, Anda dapat membuat panggilan ke Callable dan Runnable pada eksekutor thread tunggal, membuat mekanisme ini mirip dengan antrian pengiriman serial. Jadi selama pemanggil memanggil metode terbungkus Runnable Anda, thread panggilan akan mengeksekusi sangat cepat tanpa memblokir. Begitu ia memanggil Callable dibungkus dalam metode Masa Depan itu harus memblokir sampai semua item yang antri dieksekusi. Hanya kemudian metode akan kembali dengan nilai. Ini adalah mekanisme sinkronisasi.
Callableantarmuka menyatakan call()metode dan Anda perlu memberikan obat generik sebagai jenis panggilan Obyek () harus kembali -
publicinterfaceCallable<V>{/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call()throwsException;}
Runnabledi sisi lain adalah antarmuka yang menyatakan run()metode yang dipanggil saat Anda membuat Thread dengan runnable dan memanggil mulai () di atasnya. Anda juga dapat langsung memanggil run () tapi itu hanya menjalankan metode run () adalah utas yang sama.
publicinterfaceRunnable{/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/publicabstractvoid run();}
Untuk meringkas beberapa Perbedaan penting adalah
Sebuah Runnableobjek tidak mengembalikan hasil sedangkan Callableobjek mengembalikan hasilnya.
Sebuah Runnableobjek tidak bisa melempar pengecualian diperiksa wheras sebuah Callableobjek dapat membuang pengecualian.
The Runnableantarmuka telah ada sejak Java 1.0 sedangkan Callablehanya diperkenalkan di Jawa 1.5.
Beberapa kesamaan termasuk
Contoh kelas yang mengimplementasikan antarmuka Runnable atau Callable berpotensi dieksekusi oleh utas lainnya.
Contoh antarmuka Callable dan Runnable dapat dieksekusi oleh ExecutorService melalui metode submit ().
Keduanya adalah antarmuka fungsional dan dapat digunakan dalam ekspresi Lambda sejak Java8.
Metode dalam antarmuka ExecutorService adalah
<T>Future<T> submit(Callable<T> task);Future<?> submit(Runnable task);<T>Future<T> submit(Runnable task, T result);
Tujuan dari antarmuka ini dari dokumentasi oracle:
Antarmuka runnable harus diimplementasikan oleh setiap kelas yang instansnya dimaksudkan untuk dieksekusi oleh a Thread. Kelas harus mendefinisikan metode tanpa argumen yang dipanggil run.
Callable : Suatu tugas yang mengembalikan hasil dan dapat mengeluarkan pengecualian. Pelaksana mendefinisikan metode tunggal tanpa argumen yang disebut panggilan. The Callableantarmuka mirip dengan Runnable, dalam bahwa keduanya dirancang untuk kelas yang contoh yang berpotensi dieksekusi oleh thread lain. RunnableNamun, A tidak mengembalikan hasil dan tidak bisa melempar pengecualian yang diperiksa.
Perbedaan lainnya:
Anda dapat lulus Runnableuntuk membuat Utas . Tetapi Anda tidak dapat membuat Utas baru dengan melewati Callablesebagai parameter. Anda dapat meneruskan Callable hanya ke ExecutorServiceinstance.
publicclassHelloRunnableimplementsRunnable{publicvoid run(){System.out.println("Hello from a thread!");}publicstaticvoid main(String args[]){(newThread(newHelloRunnable())).start();}}
Gunakan Runnableuntuk api dan lupakan panggilan. Gunakan Callableuntuk memverifikasi hasilnya.
Callabledapat diteruskan ke memanggil semua metode tidak seperti Runnable. Metode invokeAnydan invokeAllmelakukan bentuk-bentuk eksekusi massal yang paling umum berguna, mengeksekusi kumpulan tugas dan kemudian menunggu setidaknya satu, atau semua, untuk menyelesaikan
Perbedaan sepele: nama metode yang akan diterapkan => run()untuk Runnabledan call()untuk Callable.
Seperti yang sudah disebutkan di sini, Callable adalah antarmuka yang relatif baru dan diperkenalkan sebagai bagian dari paket konkurensi. Baik Callable dan Runnable dapat digunakan dengan eksekutor. Kelas Utas (yang mengimplementasikan Runnable sendiri) hanya mendukung Runnable.
Anda masih bisa menggunakan Runnable dengan eksekutor. Keuntungan Callable yang dapat Anda kirimkan ke pelaksana dan segera mendapatkan kembali hasil Masa Depan yang akan diperbarui ketika eksekusi selesai. Hal yang sama dapat diterapkan dengan Runnable, tetapi dalam hal ini Anda harus mengelola hasilnya sendiri. Misalnya Anda dapat membuat antrian hasil yang akan menampung semua hasil. Utas lainnya dapat menunggu di antrean ini dan menangani hasil yang tiba.
saya bertanya-tanya apa contoh pada utas melemparkan pengecualian di java? akankah utas utama dapat menangkap pengecualian itu? Jika tidak, saya tidak akan menggunakan Callable. Alex, apakah Anda memiliki wawasan tentang ini? Terima kasih!
triliunan
1
Kode berjalan di utas khusus karena kode lain dapat membuang pengecualian. Untuk menangkapnya di utas lain Anda harus melakukan beberapa upaya baik menggunakan mekanisme notifikasi khusus (misalnya berdasarkan pendengar) atau dengan menggunakan Futureatau dengan menambahkan kait yang menangkap semua pengecualian yang tidak dipikirkan
AlexR
Info bagus! Terima kasih, Alex! :)
triliunan
1
Saya memutakhirkan jawaban ini karena menegaskan (dengan benar jika diambil pada nilai nominal) seseorang harus menggunakan model kumpulan thread dengan objek yang dapat dipanggil. Kelihatannya hal yang disayangkan tentang ini adalah bahwa seseorang tidak dapat memperluas Threaduntuk menggunakan Callableantarmuka yang bermakna sehingga satu utas dapat disesuaikan untuk melakukan hal-hal yang dapat dipanggil dan hal-hal lain yang mungkin diinginkan pengembang. Jika ada orang yang membaca komentar ini berpikir saya salah, saya ingin tahu lebih baik ...
8
+-------------------------------------+--------------------------------------------------------------------------------------------------+|Runnable|Callable<T>|+-------------------------------------+--------------------------------------------------------------------------------------------------+|Introduced in Java1.0 of java.lang |Introduced in Java1.5 of java.util.concurrent library ||Runnable cannot be parametrized |Callable is a parametrized type whose type parameter indicates the return type of its run method ||Runnable has run() method |Callable has call() method ||Runnable.run() returns void|Callable.call() returns a value of Type T ||Can not throwCheckedExceptions|CanthrowCheckedExceptions|+-------------------------------------+--------------------------------------------------------------------------------------------------+
Para perancang Java merasa perlu memperluas kemampuan Runnableantarmuka, tetapi mereka tidak ingin memengaruhi penggunaan Runnableantarmuka dan mungkin itulah alasan mengapa mereka menggunakan antarmuka terpisah bernama CallableJava 1.5 daripada mengubah yang sudah ada. Runnableantarmuka yang ada yang telah menjadi bagian dari Java sejak Java 1.0. sumber
Sangat penting untuk menekankan bahwa Pengecualian yang diperiksa , bukan RuntimeException
BertKing
5
Callable dan Runnable keduanya mirip satu sama lain dan dapat digunakan dalam mengimplementasikan utas. Dalam hal menerapkan Runnable Anda harus menerapkan metode run () tetapi dalam kasus callable Anda harus perlu menerapkan metode panggilan () , kedua metode ini bekerja dengan cara yang sama tetapi metode panggilan () memiliki lebih banyak fleksibilitas. Ada beberapa perbedaan di antara mereka.
Perbedaan antara Runnable dan callable seperti di bawah ini -
1) Metode run () dari runnable return void , artinya jika Anda ingin utas Anda mengembalikan sesuatu yang dapat Anda gunakan lebih lanjut maka Anda tidak punya pilihan dengan metode Runnable run () . Ada solusi 'Callable' , Jika Anda ingin mengembalikan sesuatu dalam bentuk objek maka Anda harus menggunakan Callable, bukan Runnable . Antarmuka yang dapat dipanggil memiliki metode 'panggilan ()' yang mengembalikan Objek .
Metode tanda tangan - Runnable->
publicvoid run(){}
Callable->
publicObject call(){}
2) Dalam hal metode Runnable run () jika ada pengecualian yang diperiksa muncul maka Anda harus perlu ditangani dengan blok coba tangkap , tetapi dalam kasus metode Callable call () Anda dapat melempar pengecualian yang diperiksa seperti di bawah ini
publicObject call()throwsException{}
3) Runnable berasal dari versi legacy java 1.0 , tetapi callable datang dalam versi Java 1.5 dengan kerangka Executer .
Jika Anda terbiasa dengan Pelaksana maka Anda harus menggunakan Callable bukan Runnable .
Runnable (vs) Callable menjadi poin ketika kita menggunakan kerangka Executer.
ExecutorService adalah subinterface dari Executor, yang menerima tugas Runnable dan Callable.
Multi-Threading sebelumnya dapat dicapai menggunakan Interface Sejak 1.0 , tetapi di sini masalahnya adalah setelah menyelesaikan tugas utas kami tidak dapat mengumpulkan informasi Threads. Untuk mengumpulkan data, kami dapat menggunakan bidang Statis.Runnable
Contoh Pisahkan utas untuk mengumpulkan setiap data siswa.
staticHashMap<String,List> multiTasksData =newHashMap();publicstaticvoid main(String[] args){Thread t1 =newThread(newRunnableImpl(1),"T1");Thread t2 =newThread(newRunnableImpl(2),"T2");Thread t3 =newThread(newRunnableImpl(3),"T3");
multiTasksData.put("T1",newArrayList());// later get the value and update it.
multiTasksData.put("T2",newArrayList());
multiTasksData.put("T3",newArrayList());}
Untuk mengatasi masalah ini, mereka telah memperkenalkan Sejak 1.5 yang mengembalikan hasil dan dapat melempar pengecualian.Callable<V>
Metode Single Abstract : Kedua antarmuka Callable dan Runnable memiliki metode abstrak tunggal, yang berarti mereka dapat digunakan dalam ekspresi lambda di java 8.
Jawaban:
Lihat penjelasannya di sini .
sumber
Pada dasarnya ya. Lihat jawaban untuk pertanyaan ini . Dan javadoc untuk
Callable
.Karena
Runnable
antarmuka tidak dapat melakukan semua yangCallable
dilakukannya!Runnable
telah ada sejak Java 1.0, tetapiCallable
hanya diperkenalkan di Java 1.5 ... untuk menangani kasus penggunaan yangRunnable
tidak mendukung. Secara teori, tim Java bisa saja mengubah tanda tanganRunnable.run()
metode ini, tetapi ini akan merusak kompatibilitas biner dengan kode pra-1.5, yang membutuhkan pengodean ulang saat memigrasi kode Java lama ke JVM yang lebih baru. Itu adalah TIDAK-TIDAK-yang-BESAR. Java berusaha keras untuk kompatibel ke belakang ... dan itu menjadi salah satu nilai jual terbesar Java untuk komputasi bisnis.Dan, jelas, ada kasus penggunaan di mana tugas tidak perlu mengembalikan hasil atau melemparkan pengecualian yang diperiksa. Untuk kasus penggunaan
Runnable
tersebut , menggunakan lebih ringkas daripada menggunakanCallable<Void>
dan mengembalikan nilai dummy (null
) daricall()
metode.sumber
Runnable
ada (sebagian besar) untuk alasan kompatibilitas ke belakang. Tapi bukankah ada situasi di mana tidak perlu atau terlalu mahal untuk mengimplementasikan (atau membutuhkan)Callable
antarmuka (misalnya, dalamScheduledFuture<?> ScheduledExecutorService.schedule(Runnable command, long delay, TimeUnit unit)
)? Jadi bukankah ada manfaat untuk mempertahankan kedua antarmuka dalam bahasa bahkan sejarah tidak memaksa hasil saat ini?Runnable
akan dimodifikasi jika tidak ada keharusan untuk menjaga kompatibilitas. The "boilerplate"return null;
adalah argumen yang lemah. (Setidaknya, itu akan menjadi keputusan saya ... dalam konteks hipotetis di mana Anda dapat mengabaikan kompatibilitas ke belakang.)Callable
perlu menerapkancall()
metode sementaraRunnable
kebutuhan untuk menerapkanrun()
metode.Callable
dapat mengembalikan nilai tetapiRunnable
tidak bisa.Callable
dapat membuang pengecekan yang dicek tetapiRunnable
tidak bisa.A
Callable
dapat digunakan denganExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)
metode tetapiRunnable
tidak bisa.sumber
Saya menemukan ini di blog lain yang dapat menjelaskan sedikit lebih banyak perbedaan ini :
Meskipun kedua antarmuka diimplementasikan oleh kelas-kelas yang ingin dieksekusi di utas eksekusi yang berbeda, tetapi ada beberapa perbedaan antara dua antarmuka yaitu:
Callable<V>
instance mengembalikan hasil dari tipeV
, sedangkanRunnable
instance tidak.Callable<V>
instance dapat membuang pengecualian yang diperiksa, sedangkan sebuahRunnable
instance tidak bisaPara perancang Java merasa perlu memperluas kemampuan
Runnable
antarmuka, tetapi mereka tidak ingin memengaruhi penggunaanRunnable
antarmuka dan mungkin itulah alasan mengapa mereka menggunakan antarmuka terpisah bernamaCallable
Java 1.5 daripada mengubah yang sudah ada. yang adaRunnable
.sumber
Mari kita lihat di mana orang akan menggunakan Runnable dan Callable.
Runnable dan Callable keduanya berjalan pada utas yang berbeda dari utas panggilan. Tetapi Callable dapat mengembalikan nilai dan Runnable tidak bisa. Jadi di mana ini benar-benar berlaku.
Runnable : Jika Anda memiliki tugas kebakaran dan lupa kemudian gunakan Runnable. Masukkan kode Anda di dalam Runnable dan ketika metode run () dipanggil, Anda dapat melakukan tugas Anda. Utas panggilan benar-benar tidak peduli ketika Anda melakukan tugas Anda.
Callable : Jika Anda mencoba mengambil nilai dari suatu tugas, maka gunakan Callable. Sekarang callable sendiri tidak akan melakukan pekerjaan itu. Anda akan membutuhkan Masa Depan yang dapat Anda gunakan untuk Callable Anda dan dapatkan nilai-nilai Anda di future.get (). Di sini utas panggilan akan diblokir sampai Masa Depan kembali dengan hasil yang pada gilirannya menunggu metode panggilan Callable () untuk dieksekusi.
Jadi pikirkan sebuah antarmuka ke kelas target di mana Anda memiliki metode terbungkus Runnable dan Callable. Kelas panggilan akan memanggil metode antarmuka Anda secara acak tanpa mengetahui Runnable dan yang Callable. Metode Runnable akan mengeksekusi secara tidak sinkron, sampai metode Callable dipanggil. Di sini utas kelas panggilan akan diblokir karena Anda mengambil nilai dari kelas target Anda.
CATATAN: Di dalam kelas target Anda, Anda dapat membuat panggilan ke Callable dan Runnable pada eksekutor thread tunggal, membuat mekanisme ini mirip dengan antrian pengiriman serial. Jadi selama pemanggil memanggil metode terbungkus Runnable Anda, thread panggilan akan mengeksekusi sangat cepat tanpa memblokir. Begitu ia memanggil Callable dibungkus dalam metode Masa Depan itu harus memblokir sampai semua item yang antri dieksekusi. Hanya kemudian metode akan kembali dengan nilai. Ini adalah mekanisme sinkronisasi.
sumber
Callable
antarmuka menyatakancall()
metode dan Anda perlu memberikan obat generik sebagai jenis panggilan Obyek () harus kembali -Runnable
di sisi lain adalah antarmuka yang menyatakanrun()
metode yang dipanggil saat Anda membuat Thread dengan runnable dan memanggil mulai () di atasnya. Anda juga dapat langsung memanggil run () tapi itu hanya menjalankan metode run () adalah utas yang sama.Untuk meringkas beberapa Perbedaan penting adalah
Runnable
objek tidak mengembalikan hasil sedangkanCallable
objek mengembalikan hasilnya.Runnable
objek tidak bisa melempar pengecualian diperiksa wheras sebuahCallable
objek dapat membuang pengecualian.Runnable
antarmuka telah ada sejak Java 1.0 sedangkanCallable
hanya diperkenalkan di Jawa 1.5.Beberapa kesamaan termasuk
Metode dalam antarmuka ExecutorService adalah
sumber
Tujuan dari antarmuka ini dari dokumentasi oracle:
Antarmuka runnable harus diimplementasikan oleh setiap kelas yang instansnya dimaksudkan untuk dieksekusi oleh a
Thread
. Kelas harus mendefinisikan metode tanpa argumen yang dipanggilrun
.Callable : Suatu tugas yang mengembalikan hasil dan dapat mengeluarkan pengecualian. Pelaksana mendefinisikan metode tunggal tanpa argumen yang disebut panggilan. The
Callable
antarmuka mirip denganRunnable
, dalam bahwa keduanya dirancang untuk kelas yang contoh yang berpotensi dieksekusi oleh thread lain.Runnable
Namun, A tidak mengembalikan hasil dan tidak bisa melempar pengecualian yang diperiksa.Perbedaan lainnya:
Anda dapat lulus
Runnable
untuk membuat Utas . Tetapi Anda tidak dapat membuat Utas baru dengan melewatiCallable
sebagai parameter. Anda dapat meneruskan Callable hanya keExecutorService
instance.Contoh:
Gunakan
Runnable
untuk api dan lupakan panggilan. GunakanCallable
untuk memverifikasi hasilnya.Callable
dapat diteruskan ke memanggil semua metode tidak sepertiRunnable
. MetodeinvokeAny
daninvokeAll
melakukan bentuk-bentuk eksekusi massal yang paling umum berguna, mengeksekusi kumpulan tugas dan kemudian menunggu setidaknya satu, atau semua, untuk menyelesaikanPerbedaan sepele: nama metode yang akan diterapkan =>
run()
untukRunnable
dancall()
untukCallable
.sumber
Seperti yang sudah disebutkan di sini, Callable adalah antarmuka yang relatif baru dan diperkenalkan sebagai bagian dari paket konkurensi. Baik Callable dan Runnable dapat digunakan dengan eksekutor. Kelas Utas (yang mengimplementasikan Runnable sendiri) hanya mendukung Runnable.
Anda masih bisa menggunakan Runnable dengan eksekutor. Keuntungan Callable yang dapat Anda kirimkan ke pelaksana dan segera mendapatkan kembali hasil Masa Depan yang akan diperbarui ketika eksekusi selesai. Hal yang sama dapat diterapkan dengan Runnable, tetapi dalam hal ini Anda harus mengelola hasilnya sendiri. Misalnya Anda dapat membuat antrian hasil yang akan menampung semua hasil. Utas lainnya dapat menunggu di antrean ini dan menangani hasil yang tiba.
sumber
Future
atau dengan menambahkan kait yang menangkap semua pengecualian yang tidak dipikirkanThread
untuk menggunakanCallable
antarmuka yang bermakna sehingga satu utas dapat disesuaikan untuk melakukan hal-hal yang dapat dipanggil dan hal-hal lain yang mungkin diinginkan pengembang. Jika ada orang yang membaca komentar ini berpikir saya salah, saya ingin tahu lebih baik ...Para perancang Java merasa perlu memperluas kemampuan
Runnable
antarmuka, tetapi mereka tidak ingin memengaruhi penggunaanRunnable
antarmuka dan mungkin itulah alasan mengapa mereka menggunakan antarmuka terpisah bernamaCallable
Java 1.5 daripada mengubah yang sudah ada.Runnable
antarmuka yang ada yang telah menjadi bagian dari Java sejak Java 1.0. sumbersumber
Perbedaan antara Callable dan Runnable adalah sebagai berikut:
sumber
Callable dan Runnable keduanya mirip satu sama lain dan dapat digunakan dalam mengimplementasikan utas. Dalam hal menerapkan Runnable Anda harus menerapkan metode run () tetapi dalam kasus callable Anda harus perlu menerapkan metode panggilan () , kedua metode ini bekerja dengan cara yang sama tetapi metode panggilan () memiliki lebih banyak fleksibilitas. Ada beberapa perbedaan di antara mereka.
Perbedaan antara Runnable dan callable seperti di bawah ini -
1) Metode run () dari runnable return void , artinya jika Anda ingin utas Anda mengembalikan sesuatu yang dapat Anda gunakan lebih lanjut maka Anda tidak punya pilihan dengan metode Runnable run () . Ada solusi 'Callable' , Jika Anda ingin mengembalikan sesuatu dalam bentuk objek maka Anda harus menggunakan Callable, bukan Runnable . Antarmuka yang dapat dipanggil memiliki metode 'panggilan ()' yang mengembalikan Objek .
Metode tanda tangan - Runnable->
Callable->
2) Dalam hal metode Runnable run () jika ada pengecualian yang diperiksa muncul maka Anda harus perlu ditangani dengan blok coba tangkap , tetapi dalam kasus metode Callable call () Anda dapat melempar pengecualian yang diperiksa seperti di bawah ini
3) Runnable berasal dari versi legacy java 1.0 , tetapi callable datang dalam versi Java 1.5 dengan kerangka Executer .
Jika Anda terbiasa dengan Pelaksana maka Anda harus menggunakan Callable bukan Runnable .
Semoga kamu mengerti.
sumber
Runnable (vs) Callable menjadi poin ketika kita menggunakan kerangka Executer.
ExecutorService adalah subinterface dari
Executor
, yang menerima tugas Runnable dan Callable.Multi-Threading sebelumnya dapat dicapai menggunakan Interface Sejak 1.0 , tetapi di sini masalahnya adalah setelah menyelesaikan tugas utas kami tidak dapat mengumpulkan informasi Threads. Untuk mengumpulkan data, kami dapat menggunakan bidang Statis.
Runnable
Contoh Pisahkan utas untuk mengumpulkan setiap data siswa.
Untuk mengatasi masalah ini, mereka telah memperkenalkan Sejak 1.5 yang mengembalikan hasil dan dapat melempar pengecualian.
Callable<V>
Metode Single Abstract : Kedua antarmuka Callable dan Runnable memiliki metode abstrak tunggal, yang berarti mereka dapat digunakan dalam ekspresi lambda di java 8.
Ada beberapa cara berbeda untuk mendelegasikan tugas untuk dieksekusi ke ExecutorService .
execute(Runnable task):void
peti utas baru tetapi tidak memblokir utas atau utas penelepon karena metode ini kembali batal.submit(Callable<?>):Future<?>
,submit(Runnable):Future<?>
peti utas baru dan blok utas utama saat Anda menggunakan future.get () .Contoh menggunakan Interfaces Runnable, Callable with Executor framework.
sumber
Ini adalah semacam konvensi penamaan antarmuka yang cocok dengan pemrograman fungsional
sumber