Setelah menjalankan wait (), berapa lama sebuah thread menunggu jika tidak mendapat pemberitahuan dari thread lain?

Aug 16 2020

Dalam contoh di bawah ini, karena main-thread tidak mendapatkan pemberitahuan dari thread turunan, itu harus menunggu selamanya. Tetapi main-thread sedang dieksekusi dan output dari contoh di bawah ini adalah:

c
l
total: 19900

Mengapa utas utama dieksekusi?

public class ThreadX extends Thread {
    static int total = 0;

    public void run() {
        synchronized (this) {
            for (int i = 0; i < 200; i++) {
                total = total + i;
            }
            System.out.println("c");

        }
    }

    public static void main(String[] args) throws InterruptedException {
        ThreadX t = new ThreadX();

        t.start();
        synchronized (t) {
            t.wait();
            System.out.println("l");
        }

        System.out.println("total: " + total);

    }
}

Jawaban

10 akuzminykh Aug 16 2020 at 09:58

Jawaban untuk badan pertanyaan

Lihat Thread#join(long):

[...] Sebagai thread mengakhiri this.notifyAllmetode ini dipanggil. [...]

Perhatikan bahwa Thread#join()memanggil fungsi itu dengan 0, yang artinya selamanya.

[...] Batas waktu 0 berarti menunggu selamanya.

Jadi dalam kasus Anda di sini thanya memanggil notifyAllketika itu berakhir, yang memberi tahu utas utama yang menunggu t.


Perilaku tidak intuitif ini adalah alasan mengapa mereka menulis yang berikut ini dalam dokumentasi:

Disarankan bahwa aplikasi tidak menggunakan wait, notifyatau notifyAllpada Threadkasus.

Jawaban atas judul pertanyaan

Check out Object#wait(atau JLS (17.2.1. Tunggu) ):

Sebuah utas dapat aktif tanpa pemberitahuan, interupsi, atau waktu habis, yang disebut bangun palsu. Meskipun hal ini jarang terjadi dalam praktik, aplikasi harus menjaganya dengan menguji kondisi yang seharusnya menyebabkan thread terbangun, dan terus menunggu jika kondisinya tidak memuaskan.

Jadi utas di Java bisa aktif kapan saja. Bangun palsu tidak mungkin terjadi tetapi itu bisa terjadi.