Saya membuat aplikasi Java dengan aplikasi-logika-utas dan basis-akses-utas. Keduanya bertahan selama masa aplikasi dan keduanya harus berjalan pada saat yang sama (satu berbicara ke server, satu berbicara dengan pengguna; ketika aplikasi sepenuhnya dimulai, saya perlu keduanya untuk bekerja).
Namun, saat startup, saya perlu memastikan bahwa awalnya utas aplikasi menunggu hingga utas db siap (saat ini ditentukan dengan polling metode khusus dbthread.isReady()
). Saya tidak keberatan jika aplikasi thread memblokir sampai thread db siap.
Thread.join()
tidak terlihat seperti solusi - utas db hanya keluar saat aplikasi ditutup.
while (!dbthread.isReady()) {}
jenis bekerja, tetapi loop kosong mengkonsumsi banyak siklus prosesor.
Ada ide lain? Terima kasih.
sumber
a
sedang menunggu objek,synchronised(object)
bagaimana utas lain dapatsynchronized(object)
menelponobject.notifyAll()
? Dalam program saya, semuanya macet disynchronozed
blok.object.wait()
secara efektif membuka kunci pada objek itu. Ketika utas kedua "keluar" dari blok yang disinkronkan, maka objek lain dilepaskan dariwait
metode dan mendapatkan kembali kunci pada titik itu.Gunakan CountDownLatch dengan penghitung 1.
Sekarang di utas aplikasi do-
Di utas db, setelah Anda selesai, lakukan -
sumber
countDown()
ke dalamfinally{}
blokPersyaratan ::
Jawaban ::
Pekerjaan selesai!! Lihat contoh di bawah ini
Output dari program ini ::
Anda dapat melihat bahwa membutuhkan 6sec sebelum menyelesaikan tugasnya yang lebih besar dari utas lainnya. Jadi Future.get () menunggu hingga tugas selesai.
Jika Anda tidak menggunakan future.get () itu tidak menunggu untuk menyelesaikan dan mengeksekusi konsumsi waktu berdasarkan.
Semoga Sukses dengan konkurensi Java.
sumber
CountdownLatch
es, tetapi Anda adalah pendekatan yang jauh lebih fleksibel.Banyak jawaban yang benar tetapi tanpa contoh sederhana .. Berikut adalah cara mudah dan sederhana cara menggunakannya
CountDownLatch
:sumber
Gunakan kelas ini seperti ini, lalu:
Buat ThreadEvent:
Dalam metode ini menunggu hasil:
Dan dalam metode yang menciptakan hasil setelah semua hasil telah dibuat:
EDIT:
(Maaf untuk mengedit posting ini, tetapi kode ini memiliki kondisi lomba yang sangat buruk dan saya tidak memiliki reputasi yang cukup untuk berkomentar)
Anda hanya dapat menggunakan ini jika Anda yakin 100% bahwa sinyal () dipanggil setelah menunggu (). Ini adalah salah satu alasan utama mengapa Anda tidak dapat menggunakan objek Java seperti misalnya Windows Events.
Kode jika dijalankan dalam urutan ini:
maka utas 2 akan menunggu selamanya . Ini karena Object.notify () hanya membangunkan salah satu utas yang sedang berjalan. Utas yang menunggu nanti tidak dibangunkan. Ini sangat berbeda dari bagaimana saya berharap acara bekerja, di mana suatu peristiwa ditandai sampai a) menunggu atau b) secara eksplisit mengatur ulang.
Catatan: Sebagian besar waktu, Anda harus menggunakan notifyAll (), tetapi ini tidak relevan dengan masalah "tunggu selamanya" di atas.
sumber
Coba kelas CountDownLatch keluar dari
java.util.concurrent
paket, yang menyediakan mekanisme sinkronisasi tingkat yang lebih tinggi, yang jauh lebih rentan kesalahan daripada hal-hal tingkat rendah.sumber
Anda bisa melakukannya menggunakan Exchanger objek dibagi antara dua utas:
Dan di utas kedua:
Seperti yang telah dikatakan orang lain, jangan ambil kode copy-paste ini. Baca dulu.
sumber
The Future antarmuka dari
java.lang.concurrent
paket ini dirancang untuk memberikan akses ke hasil dihitung di thread lain.Lihatlah FutureTask dan ExecutorService untuk cara yang sudah jadi dalam melakukan hal semacam ini.
Saya sangat merekomendasikan membaca Java Concurrency In Practice kepada siapa pun yang tertarik pada concurrency dan multithreading. Jelas berkonsentrasi pada Jawa, tetapi ada banyak daging bagi siapa pun yang bekerja dalam bahasa lain juga.
sumber
Jika Anda menginginkan sesuatu yang cepat dan kotor, Anda bisa menambahkan panggilan Thread.sleep () dalam loop sementara Anda. Jika pustaka database adalah sesuatu yang tidak dapat Anda ubah, maka sebenarnya tidak ada solusi mudah lainnya. Polling database sampai siap dengan masa tunggu tidak akan mematikan kinerja.
Bukan sesuatu yang bisa Anda sebut kode elegan, tetapi menyelesaikan pekerjaan.
Jika Anda dapat mengubah kode database, maka menggunakan mutex seperti yang diusulkan dalam jawaban lain lebih baik.
sumber
Ini berlaku untuk semua bahasa:
Anda ingin memiliki model acara / pendengar. Anda membuat pendengar untuk menunggu acara tertentu. Acara akan dibuat (atau diisyaratkan) di utas pekerja Anda. Ini akan memblokir utas sampai sinyal diterima alih-alih polling untuk melihat apakah suatu kondisi terpenuhi, seperti solusi yang Anda miliki saat ini.
Situasi Anda adalah salah satu penyebab kebuntuan yang paling umum - pastikan Anda memberi tanda utas lainnya terlepas dari kesalahan yang mungkin terjadi. Contoh-jika aplikasi Anda melempar pengecualian- dan tidak pernah memanggil metode untuk memberi sinyal yang lain bahwa semuanya telah selesai. Ini akan membuatnya jadi utas lainnya tidak pernah 'bangun'.
Saya menyarankan agar Anda melihat konsep menggunakan event dan event handler untuk lebih memahami paradigma ini sebelum menerapkan kasus Anda.
Atau Anda dapat menggunakan panggilan fungsi pemblokiran menggunakan mutex- yang akan menyebabkan utas menunggu sumber daya menjadi gratis. Untuk melakukan ini, Anda perlu sinkronisasi utas yang baik - seperti:
sumber
Anda bisa membaca dari antrian pemblokiran di satu utas dan menulisnya di utas lain.
sumber
Sejak
join()
telah dikesampingkanAnda dapat mempertimbangkan alternatif lain:
meminta semua dari
ExecutorService
ForkJoinPool atau newWorkStealingPool dari
Executors
(karena Jawa 8 rilis)sumber
Gagasan ini bisa berlaku? Jika Anda menggunakan CountdownLatches atau Semaphores berfungsi sempurna tetapi jika Anda mencari jawaban termudah untuk wawancara saya pikir ini bisa diterapkan.
sumber