Saya sering menjelajah. Mengenai Notify dan Notifyall di Java, orang sering memiliki pernyataan berikut:
Notify hanya akan memberi tahu objek yang menunggu, sementara NotifyAll akan memberi tahu semua objek yang menunggu, dan semua objek akan terus berjalan.
Dan, tampaknya ada contoh untuk membuktikannya. Pernyataan di atas dapat dikatakan benar atau tidak. Alasannya adalah salah satu dari mereka sangat penting. Pernyataan resmi adalah sebagai berikut:
Tunggu, beri tahu, beri tahu semua:
Metode ini hanya boleh dipanggil oleh utas yang merupakan pemilik monitor objek ini. Benang dapat menjadi pemilik monitor objek ini dalam salah satu dari tiga cara:
Dengan mengeksekusi metode instance sinkron dari objek ini.
Tubuh pernyataan yang disinkronkan dieksekusi dengan mengeksekusi pernyataan yang disinkronkan pada objek ini.
Untuk objek tipe kelas, Anda dapat menjalankan metode statis kelas sinkron.
Hanya satu utas yang memiliki monitor objek pada satu waktu.
Pernyataan di atas dikutip dari Javadoc. Ini berarti bahwa dalam panggilan, monitor objek (mis., Kunci) harus diadakan, yang dapat kita pahami sebagai berjalan dalam metode yang disinkronkan. Maka makna implisit dari pernyataan ini adalah bahwa jika Anda ingin melanjutkan blok kode yang terkandung dalam blok sinkronisasi, Anda perlu memperoleh kembali kunci. Kalimat ini dijelaskan dalam Javadoc:
Tunggu
Metode ini menyebabkan utas saat ini (disebut T) menempatkan dirinya di set menunggu objek dan kemudian meninggalkan semua persyaratan sinkronisasi pada objek ini. Untuk tujuan penjadwalan utas, utas T dinonaktifkan dan sedang dalam hibernasi sebelum salah satu dari empat situasi berikut terjadi:
Beberapa utas lain memanggil metode pemberitahuan dari objek ini, dan utas t kebetulan dipilih secara opsional sebagai utas bangun.
Beberapa utas lain memanggil metode pemberitahuan Objek ini.
Beberapa utas lainnya mengganggu utas T.
Kira -kira waktu aktual yang ditentukan telah tercapai. Namun, jika batas waktu adalah nol, waktu aktual tidak diperhitungkan dan utas akan menunggu sampai pemberitahuan diperoleh.
Kemudian, Thread T dihapus dari set menunggu objek dan penjadwalan utas dilakukan lagi. Utas kemudian bersaing dengan utas lain dengan cara konvensional untuk mendapatkan hak untuk menyinkronkan pada objek; Setelah kontrol atas objek diperoleh, semua deklarasi sinkronisasi pada objek akan dikembalikan ke keadaan mereka sebelumnya, yaitu untuk menelepon menunggu
Situasi saat metodenya. Thread T kemudian kembali dari panggilan ke metode tunggu. Oleh karena itu, ketika kembali dari metode tunggu, status sinkronisasi objek dan utas T persis sama seperti saat memanggil metode tunggu.
Artinya, kunci harus diperoleh ulang, sehingga untuk notifyall, semua utas telah diberitahu. Namun, utas ini akan bersaing, dan hanya satu utas yang akan berhasil memperoleh kunci. Sebelum utas ini dijalankan, utas lain harus menunggu (tetapi tidak perlu memberi tahu semua pemberitahuan di sini, karena diberitahu semua, dan hanya perlu untuk mendapatkan kunci). Ada kode berikut yang dapat mereproduksi fenomena ini.
Pertama, tentukan kelas utas yang dapat berjalan, sebagai berikut:
objek akhir statis privat OBJ = objek baru (); Static Class R mengimplementasikan runnable {int i; R (int i) {this.i = i; } public void run () {coba {disinkronkan (obj) {System.out.println ("thread->" + i + "tunggu"); obj.wait (); System.out.println ("Thread->" + i + "Running"); Thread.sleep (30000); }} catch (Exception e) {e.printstacktrace (); }}} Perhatikan bagian dalam metode run di atas. Setelah menunggu (), kami mencetak kalimat, dan kemudian menjeda kode saat ini selama 30 detik. Mengenai metode tidur, itu digambarkan sebagai berikut:
Utas tidak kehilangan kepemilikan monitor apa pun.
Artinya, kuncinya masih dipegang.
Kemudian, tentukan metode utama untuk menjalankan utas ini sebagai berikut:
Thread [] rs = utas baru [10]; untuk (int i = 0; i <10; i ++) {rs [i] = utas baru (baru r (i)); } untuk (utas r: rs) {r.start (); } Thread.sleep (5000); disinkronkan (obj) {obj.notifyall (); }Kami mendefinisikan 10 utas dan kemudian menjalankan semuanya. Karena ada menunggu, 10 utas akan menunggu setelah mencetak "Mulai Jalankan". Kemudian metode utama memanggil NotifyAll. Output di sini akan muncul sebagai berikut:
Thread-> 0 menunggu utas-> 4 menunggu utas-> 5 menunggu utas-> 3 menunggu utas-> 2 menunggu utas-> 1 menunggu utas-> 6 menunggu utas-> 7 menunggu utas-> 8 menunggu utas-> 9 menunggu utas-> 9 berjalan
... tidak ada output lain dalam 30 detik
Dalam output di atas, setelah menunggu, hanya satu utas mengeluarkan pernyataan "Menjalankan", dan untuk jangka waktu tertentu (30 detik di sini), tidak akan ada output lain. Dengan kata lain, utas lain tidak akan menghasilkan antara kunci yang dipegang oleh kode saat ini.
Kesimpulan terakhir adalah: jika utas penantian ingin terus berjalan, ia harus memenuhi dua syarat:
Utas lainnya memberi tahu atau pemberitahuan telah diberitahukan, dan utas saat ini telah diberitahu.
Setelah bersaing dengan utas lain untuk mengunci, dua kondisi berhasil diperoleh untuk mengunci, dan tak satu pun dari mereka yang hilang. Faktanya, pada tingkat implementasi, memberi tahu dan memberi tahu semua efek yang sama, dan utas akan terus berjalan. Tetapi NotifyAls dibebaskan. Kebutuhan untuk memberi tahu utas lain setelah utas berjalan, karena telah diberitahukan. Kapan menggunakan notify dan kapan menggunakan notifyall, itu tergantung pada situasi aktual.
Di atas adalah kompilasi informasi untuk Java memberi tahu dan memberi tahu semua. Kami akan terus menambahkan informasi yang relevan di masa mendatang. Terima kasih atas dukungan Anda untuk situs web ini!