Saya menggunakan multi-threading di java untuk program saya. Saya telah menjalankan utas dengan sukses tetapi ketika saya menggunakan Thread.wait()
, itu sedang melempar java.lang.IllegalMonitorStateException
. Bagaimana saya bisa membuat utas menunggu sampai diberitahukan?
java
multithreading
wait
prakash.panjwani
sumber
sumber
Jawaban:
Anda harus berada di
synchronized
blok agarObject.wait()
dapat bekerja.Juga, saya sarankan melihat paket concurrency daripada paket threading sekolah lama. Mereka lebih aman dan lebih mudah untuk diajak bekerja sama .
Selamat coding.
EDIT
Saya berasumsi Anda maksud
Object.wait()
sebagai pengecualian Anda adalah apa yang terjadi ketika Anda mencoba untuk mendapatkan akses tanpa memegang kunci objek.sumber
wait
didefinisikan dalamObject
, dan bukan ituThread
. Monitor menyalaThread
sedikit tidak terduga.Meskipun semua objek Java memiliki monitor, umumnya lebih baik memiliki kunci khusus:
Anda dapat sedikit lebih mudah membaca diagnostik, dengan biaya memori yang kecil (sekitar 2K per proses) dengan menggunakan kelas bernama:
Untuk
wait
ataunotify
/notifyAll
suatu objek, Anda harus memegang kunci dengansynchronized
pernyataan. Selain itu, Anda akan memerlukanwhile
perulangan untuk memeriksa kondisi bangun (temukan teks yang bagus di threading untuk menjelaskan alasannya).Untuk memberi tahu:
Sebaiknya Anda memahami bahasa Jawa dan
java.util.concurrent.locks
kunci (danjava.util.concurrent.atomic
) ketika masuk ke multithreading. Tetapi gunakanjava.util.concurrent
struktur data kapan pun Anda bisa.sumber
wait
, ya Anda tidak akan pernah bisanotify
. Namun, dalam dokumen API untukObject.wait
, "Utas melepaskan kepemilikan monitor ini". Jadi sementara diwait
dalamnya seolah-olah berada di luarsynchronized
blok melampirkan (untuk objek yang sama, mungkin beberapasynchronized
blok pada objek yang sama).Saya tahu utas ini sudah hampir 2 tahun tetapi masih harus ditutup karena saya juga datang ke sesi tanya jawab ini dengan masalah yang sama ...
Harap baca definisi illegalMonitorException ini lagi dan lagi ...
IllegalMonitorException dilemparkan untuk menunjukkan bahwa utas telah mencoba untuk menunggu di monitor objek atau untuk memberi tahu utas lain yang menunggu di monitor objek tanpa memiliki monitor yang ditentukan.
Baris ini berulang-ulang mengatakan, IllegalMonitorException muncul ketika salah satu dari 2 situasi terjadi ....
1> menunggu monitor objek tanpa memiliki monitor yang ditentukan.
2> beri tahu utas lain yang menunggu di monitor objek tanpa memiliki monitor yang ditentukan.
Beberapa mungkin sudah mendapatkan jawaban mereka ... yang semuanya tidak, maka silakan periksa 2 pernyataan ....
disinkronkan (objek)
object.wait ()
Jika kedua objek sama ... maka ilegalMonitorException tidak dapat datang.
Sekarang lagi baca definisi IllegalMonitorException dan Anda tidak akan melupakannya lagi ...
sumber
Berdasarkan komentar Anda, sepertinya Anda melakukan sesuatu seperti ini:
Ada tiga masalah.
Seperti yang dikatakan orang lain,
obj.wait()
hanya dapat dipanggil jika utas saat ini menyimpan kunci primitif / mutexobj
. Jika utas saat ini tidak menahan kunci, Anda mendapatkan pengecualian yang Anda lihat.The
thread.wait()
panggilan tidak melakukan apa yang Anda tampaknya akan mengharapkan untuk melakukannya. Secara khusus,thread.wait()
tidak menyebabkan utas yang dinominasikan menunggu. Sebaliknya itu menyebabkan utas saat ini menunggu sampai beberapa utas lainnya meneleponthread.notify()
atauthread.notifyAll()
.Sebenarnya tidak ada cara aman untuk memaksa sebuah
Thread
instance untuk berhenti jika tidak mau. (Yang terdekat dengan Java adalah yang sudah usangThread.suspend()
metode yang , tetapi metode itu secara inheren tidak aman, seperti yang dijelaskan dalam Javadoc.)Jika Anda ingin yang baru mulai
Thread
berhenti, cara terbaik untuk melakukannya adalah membuatCountdownLatch
instance dan membuat panggilan threadawait()
pada kait untuk menjeda sendiri. Utas utama kemudian akan memanggilcountDown()
kait untuk membiarkan utas yang dijeda berlanjut.Orthogonal ke poin sebelumnya, menggunakan
Thread
objek sebagai kunci / mutex dapat menyebabkan masalah. Misalnya, javadoc untukThread::join
mengatakan:sumber
Karena Anda belum memposting kode, kami agak bekerja dalam kegelapan. Apa rincian pengecualiannya?
Apakah Anda menelepon Thread.wait () dari dalam utas, atau di luarnya?
Saya menanyakan hal ini karena menurut javadoc untuk IllegalMonitorStateException, itu adalah:
Untuk memperjelas jawaban ini, panggilan untuk menunggu di utas ini juga melempar IllegalMonitorStateException, meskipun dipanggil dari dalam blok yang disinkronkan:
sumber
wait()
.worker.wait()
garis? Maka Anda harus melakukan sinkronisasi pada pekerja, bukan pada kunci.Untuk berurusan dengan IllegalMonitorStateException, Anda harus memverifikasi bahwa semua doa tunggu, beri tahu, dan beri tahu semua metode hanya terjadi ketika utas panggilan memiliki monitor yang sesuai . Solusi paling sederhana adalah dengan melampirkan panggilan-panggilan ini di dalam blok yang disinkronkan. Objek sinkronisasi yang akan dipanggil dalam pernyataan yang disinkronkan adalah yang monitornya harus diperoleh.
Berikut adalah contoh sederhana untuk memahami konsep monitor
sumber
Panggilan Thread.wait () masuk akal di dalam kode yang disinkronkan pada objek Thread.class. Saya tidak berpikir itu yang Anda maksudkan.
Anda bertanya
Anda hanya dapat membuat utas saat ini menunggu. Utas lainnya hanya dapat diminta dengan lembut untuk menunggu, jika disetujui.
Jika Anda ingin menunggu beberapa kondisi, Anda memerlukan objek kunci - objek Thread.class adalah pilihan yang sangat buruk - itu adalah AFAIK tunggal sehingga menyinkronkannya (kecuali untuk metode statis Thread) berbahaya.
Detail untuk sinkronisasi dan menunggu sudah dijelaskan oleh Tom Hawtin.
java.lang.IllegalMonitorStateException
berarti Anda mencoba untuk menunggu objek yang tidak Anda sinkronkan - itu ilegal untuk melakukannya.sumber
Tidak yakin apakah ini akan membantu orang lain atau tidak, tetapi ini adalah bagian kunci untuk memperbaiki masalah saya di pengguna "Tom Hawtin - tacklin" jawaban di atas:
Hanya fakta bahwa "kunci" dilewatkan sebagai argumen dalam sinkronisasi () dan juga digunakan dalam "kunci" .notifyAll ();
Setelah saya membuatnya di 2 tempat itu saya membuatnya bekerja
sumber
Saya menerima beberapa
IllegalMonitorStateException
saat mencoba membangun utas dalam / dariclass
utas berbeda . Dalamjava 8
Anda dapat menggunakanlock
fitur dari API Concurrency baru bukan darisynchronized
fungsi.Saya sudah menyimpan objek untuk
asynchronous
transaksi websocket di aWeakHashMap
. Solusi dalam kasus saya adalah juga menyimpanlock
objek dalamConcurrentHashMap
synchronous
balasan untuk . Catatan tersebutcondition.await
(tidak.wait
).Untuk menangani multi threading, saya menggunakan a
Executors.newCachedThreadPool()
untuk membuat kumpulan thread .sumber
Mereka yang menggunakan Java 7.0 atau versi di bawahnya dapat merujuk kode yang saya gunakan di sini dan berfungsi.
sumber