Wait () işlemini gerçekleştirdikten sonra, bir iş parçacığı diğer iş parçacıklarından bildirim almazsa ne kadar bekler?

Aug 16 2020

Aşağıdaki örnekte, ana iş parçacığı alt iş parçacığından bildirilmediğinden sonsuza kadar beklemesi gerekir. Ancak ana iş parçacığı yürütülüyor ve aşağıdaki örneğin çıktısı:

c
l
total: 19900

Ana iş parçacığı neden yürütülüyor?

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);

    }
}

Yanıtlar

10 akuzminykh Aug 16 2020 at 09:58

Soru gövdesine cevap

Kontrol edin Thread#join(long):

[...] Bir iş parçacığı sona erdiğinde this.notifyAllyöntem çağrılır. [...]

Thread#join()Bu işlevi çağırdığına dikkat edin, 0yani sonsuza kadar.

[...] 0 zaman aşımı sonsuza kadar beklemek anlamına gelir.

Yani sizin durumunuzda burada tsadece notifyAllsona erdiğinde çağırır , bu da bekleyen ana iş parçacığını bildirir t.


Bu sezgisel olmayan davranış, belgelere aşağıdakileri yazmalarının sebebidir:

Uygulamalar kullanmayın önerilir wait, notifyya notifyAllüzerinde Threaddurumlarda.

Soru başlığına cevap

Kontrol edin Object#wait(veya JLS (17.2.1. Bekleyin) ):

Bir ileti dizisi, sözde sahte uyandırma olarak bildirilmeden, kesintiye uğramadan veya zaman aşımına uğramadan uyanabilir. Bu pratikte nadiren meydana gelse de, uygulamalar iş parçacığının uyanmasına neden olması gereken koşulu test ederek ve koşul tatmin edici değilse beklemeye devam ederek buna karşı korunmalıdır.

Böylece Java'daki iş parçacıkları herhangi bir zamanda uyanabilir. Sahte bir uyandırma çok olası değildir, ancak olabilir.