Adakah yang bisa menyarankan saya bagaimana saya bisa mengirimkan parameter ke utas?
Juga, bagaimana cara kerjanya untuk kelas anonim?
java
multithreading
Steve
sumber
sumber
Consumer<T>
.Jawaban:
Anda perlu meneruskan parameter dalam konstruktor ke objek Runnable:
dan memohon demikian:
sumber
r
akan memiliki argumen yang sama, jadi jika kita ingin memberikan argumen berbeda ke beberapa Thread yang sedang berjalan,MyThread
kita perlu membuatMyThread
instance baru menggunakan argumen yang diinginkan untuk setiap Thread. Dengan kata lain, untuk mendapatkan thread dan menjalankan kita perlu membuat dua objek: Thread dan MyThread. Apakah ini dianggap buruk, bijaksana?Untuk kelas Anonim:
Menanggapi suntingan pertanyaan di sini adalah cara kerjanya untuk kelas Anonim
Kelas yang diberi nama:
Anda memiliki kelas yang memperluas Thread (atau mengimplementasikan Runnable) dan konstruktor dengan parameter yang ingin Anda sampaikan. Kemudian, ketika Anda membuat utas baru, Anda harus memberikan argumen, dan kemudian memulai utas, sesuatu seperti ini:
Runnable adalah solusi yang jauh lebih baik daripada Thread BTW. Jadi saya lebih suka:
Jawaban ini pada dasarnya sama dengan pertanyaan serupa ini: Cara meneruskan parameter ke objek Thread
sumber
parameter
langsung darirun()
metode tanpa menggunakan bidang sepertip
sama sekali. Sepertinya berhasil. Apakah ada beberapa hal multithreading halus yang saya lewatkan dengan tidak menyalinparameter
kep
sebelumnya?)
dalam contoh pertamafinal X parameter
sebelumnew Runnable()
baris, maka saya bisa mengaksesparameter
di dalamrun()
. Saya tidak perlu melakukan ekstrap = parameter
.final
tidak begitu penting lagi; itu sudah cukup jika variabel efektif final (meskipun tidak ada salahnya)melalui konstruktor dari kelas Runnable atau Thread
sumber
@Override
?@Override
secara eksplisit menyatakan bahwa itu menimpa metode abstrak di kelas Thread.Jawaban ini datang sangat terlambat, tetapi mungkin seseorang akan menemukannya berguna. Ini adalah tentang cara meneruskan parameter ke kelas
Runnable
tanpa mendeklarasikan kelas bernama (berguna untuk inliner):Tentu saja Anda dapat menunda eksekusi
start
ke momen yang lebih nyaman atau tepat. Dan terserah Anda apa yang akan menjadi tanda tanganinit
metode (sehingga mungkin diperlukan lebih banyak dan / atau argumen yang berbeda) dan tentu saja bahkan namanya, tetapi pada dasarnya Anda mendapatkan ide.Bahkan ada juga cara lain untuk mengirimkan parameter ke kelas anonim, dengan menggunakan blok initializer. Pertimbangkan ini:
Jadi semua terjadi di dalam blok initializer.
sumber
this.myParam
itu benar-benar diperlukan? Tidak bisakah Anda hanya menjatuhkan variabel pribadi dan merujuk ke variabel dari lingkup luar? Saya mengerti (tentu saja) bahwa ini memiliki beberapa implikasi, seperti variabel yang terbuka untuk diubah setelah memulai utas.Saat Anda membuat utas, Anda membutuhkan instance dari
Runnable
. Cara termudah untuk mengirimkan parameter adalah dengan mengirimkannya sebagai argumen ke konstruktor:Jika kemudian Anda ingin mengubah parameter saat utas berjalan, Anda bisa menambahkan metode setter ke kelas runnable Anda:
Setelah ini, Anda dapat mengubah nilai parameter dengan memanggil seperti ini:
Tentu saja, jika Anda ingin memicu aksi ketika parameter diubah, Anda harus menggunakan kunci, yang membuat segalanya menjadi lebih kompleks.
sumber
Untuk membuat utas, Anda biasanya membuat implementasi Runnable Anda sendiri. Lewati parameter ke utas di konstruktor kelas ini.
sumber
Anda dapat memperpanjang atau dan menyediakan parameter yang Anda inginkan. Ada contoh sederhana dalam dokumen . Saya akan port mereka di sini:
Thread
class
Runnable
class
sumber
Baik tulis kelas yang mengimplementasikan Runnable, dan berikan apa pun yang Anda butuhkan di konstruktor yang didefinisikan dengan tepat, atau tulis kelas yang memperluas Thread dengan konstruktor yang didefinisikan dengan tepat yang memanggil super () dengan parameter yang sesuai.
sumber
Pada Java 8, Anda dapat menggunakan lambda untuk menangkap parameter yang final secara efektif . Sebagai contoh:
sumber
Di Java 8 Anda dapat menggunakan
lambda
ekspresi dengan Concurrency API &ExecutorService
sebagai pengganti tingkat yang lebih tinggi untuk bekerja dengan utas secara langsung:Lihat juga
executors
javadocs .sumber
Saya tahu bahwa saya terlambat beberapa tahun, tetapi saya menemukan masalah ini dan mengambil pendekatan yang tidak ortodoks. Saya ingin melakukannya tanpa membuat kelas baru, jadi inilah yang saya buat:
sumber
Melewati parameter melalui metode start () dan run ():
sumber
Anda bisa mendapatkan kelas dari Runnable, dan selama konstruksi (katakanlah) masukkan parameter.
Kemudian jalankan menggunakan Thread.start (Runnable r);
Jika Anda berarti sementara benang sedang berjalan, maka hanya memegang referensi ke objek Anda berasal di thread memanggil, dan memanggil metode setter yang tepat (sinkronisasi mana yang sesuai)
sumber
Ada cara sederhana untuk mengirimkan parameter ke runnables. Kode:
sumber
Tidak, Anda tidak dapat meneruskan parameter ke
run()
metode. Tanda tangan memberi tahu Anda (tidak memiliki parameter). Mungkin cara termudah untuk melakukan ini adalah dengan menggunakan objek yang dibangun dengan tujuan yang mengambil parameter dalam konstruktor dan menyimpannya dalam variabel akhir:Setelah Anda melakukannya - Anda harus berhati-hati dengan integritas data objek yang Anda berikan ke 'WorkingTask'. Data sekarang akan ada di dua utas berbeda sehingga Anda harus memastikan itu adalah Utas Aman.
sumber
Satu opsi lebih lanjut; pendekatan ini memungkinkan Anda menggunakan item Runnable seperti panggilan fungsi tidak sinkron. Jika tugas Anda tidak perlu mengembalikan hasil, misalnya hanya melakukan beberapa tindakan Anda tidak perlu khawatir tentang bagaimana Anda mengembalikan "hasil".
Pola ini memungkinkan Anda menggunakan kembali suatu item, di mana Anda memerlukan semacam kondisi internal. Ketika tidak melewati parameter dalam perawatan konstruktor diperlukan untuk memediasi akses program ke parameter. Anda mungkin perlu lebih banyak memeriksa jika kasus penggunaan Anda melibatkan penelepon yang berbeda, dll.
}
Utas t = Utas baru (MyRunnable baru (parameter)); t.start ();
Jika Anda membutuhkan hasil pemrosesan, Anda juga perlu mengoordinasikan penyelesaian MyRunnable ketika sub-tugas selesai. Anda bisa menjawab panggilan kembali atau hanya menunggu di Thread 't', dll.
sumber
Khusus untuk Android
Untuk tujuan panggilan balik, saya biasanya menerapkan generik sendiri
Runnable
dengan parameter input:Penggunaannya sederhana:
Dalam manajer:
sumber
Buat variabel lokal di kelas Anda yang
extends Thread
atauimplements Runnable
.Dengan cara ini, Anda bisa melewatkan variabel saat Anda menjalankannya.
Hasil:
sumber