簡體   English   中英

Java線程等待,在一個類中通知,給出意外結果

[英]Java Threads wait, notify in one class giving unexpected results

/ 我已經將以下程序編寫為wait()和notify()。 但是在轉到First put()方法之后,線程不再前進。 誰能解釋一下我在以下代碼中所犯的錯誤。 /

public class ThreadJoin {
    public void buildThread() throws InterruptedException {
        Adder a = new Adder("Test");
        Thread t1 = new Thread(a, "First");
        Thread t2 = new Thread(a, "second");

        t1.start();
        t2.start();
    }

    public static void main(String[] args) throws InterruptedException {
        new ThreadJoin().buildThread();
    }
}

class Adder implements Runnable {
    String name;
    int i;
    private boolean suspendFlag = false;

    public Adder(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
            for(int i = 0; i < 10; i++){
                put(i);
            }

            for(int j = 0 ; j < 10; j++){
                get();
            }
    }

    public synchronized void put(int i) {
        this.i = i;

        try {
            while (suspendFlag) {
                wait();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("put: " + i+" currentThread: "+Thread.currentThread().getName());
        suspendFlag = true;
        notify();
    }

    public synchronized void get() {
        System.out.println("Entering into the get method");

        try {
            if (!suspendFlag) {
                wait();
            }
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("get: " + i+" currentThread: "+Thread.currentThread().getName());
        suspendFlag = true;
        notify();
    }
}

哪個線程First執行(例如First )將執行synchronized put方法,從而鎖定Adder對象的監視器。 在這種情況下,另一個線程( second )無法開始執行put方法,因為它無法鎖定同一Adder對象的監視器。

因此, First看到suspendFlagfalse ,因此跳過了while 它使supsedFlag true並調用notify() 當前沒有線程正在Adder對象上等待,因此對notify()的調用沒有任何作用。

當此線程結束put方法的執行時,監視器將被釋放, second可能獲取它。 如果發生這種情況,它將看到suspendFlagtrue並進入while塊,執行wait() 這樣做會釋放監視器。 suspendFlag仍然為true

執行返回到FirstFirst循環進行for然后重新調用put 它看到suspendFlagtrue並進入while循環,並調用wait()

現在,您的兩個線程都處於wait ,沒有任何notify 您的程序停頓了。

發生的情況的簡單視圖是,您有一個等待通知結構,該結構強制進行交替的putget調用。 您有兩個線程,每個線程put在其第一個get之前執行10次put調用,因此無法進行交替。 這兩個線程最終都put等待另一個進行get

你可以改變你的設計允許多put電話沒有get或更改驅動代碼,這樣一個線程並put通話,另一種則get調用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM