簡體   English   中英

關於線程等待/通知

[英]Regarding threading wait/notify

我是Java線程概念的初學者。 我通過實現等待和通知機制完成了一個小程序,其編碼如下:-

范例.java

import comp.samplecheck;

public class Example extends Thread {
public static void main(String[] args) {
    samplecheck sample = new samplecheck("First");
    samplecheck sample1 = new samplecheck("Second");
    samplecheck sample2 = new samplecheck("Third");
    samplecheck sample4 = new samplecheck("Fourth");
    samplecheck sample5 = new samplecheck("Fifth");

    sample.initiate(sample);
    sample1.initiate(sample1);
    sample2.initiate(sample2);

    try {
        Thread.sleep(1000);
        sample4.samplefunc(sample4);
    }
    catch(InterruptedException e) {
        System.out.println("Exception "+e);
    }
}
}

samplecheck.java

package comp;

import java.util.List;
import java.util.ArrayList;

public class samplecheck extends Thread {
String get_text;
samplecheck objs;
static List arr = new ArrayList();

public samplecheck(String str) {
    this.get_text = str;
}

public void run() {     
    synchronized(arr) {
        System.out.println(objs.getName()+" Started Processing");

        try {
            arr.wait();
        }
        catch(InterruptedException e) {
            System.out.println("Exception "+e);
        }

        System.out.println("Initial Array Elements Size "+arr.size());
        for(int i=0; i<100 ; i++){
            arr.add(i);
        }

        System.out.println("After Array Elements Size "+arr.size());
        System.out.println("An Object Is Notified");            
    }
}

public void initiate(samplecheck obj) {
    objs = obj;
    objs.start();
}

public void samplefunc(samplecheck obj) {
    objs = obj;

    synchronized(arr) {
        System.out.println("Notification Process");
        System.out.println("After Array Elements Size "+arr.size());
        arr.notify();
    }
}   
}

在samplecheck.java中的samplefunc函數中,如果我給arr.notify(),我可以得到正確的輸出為

    Thread-0 Started Processing
    Thread-1 Started Processing
    Thread-2 Started Processing
    Notification Process
    After Array Elements Size 0
    Initial Array Elements Size 0
    After Array Elements Size 100
    An Object Is Notified

但是如果用arr.notifyAll()而不是arr.notify(),我得到的輸出為

    Thread-0 Started Processing
    Thread-2 Started Processing
    Thread-1 Started Processing
    Notification Process
    After Array Elements Size 0
    Initial Array Elements Size 0
    After Array Elements Size 100
    An Object Is Notified
    Initial Array Elements Size 100
    After Array Elements Size 200
    An Object Is Notified
    Initial Array Elements Size 200
    After Array Elements Size 300
    An Object Is Notified

但是根據編碼的觀點,即使我給notifyAll,也只能執行在數組“ arr”上獲得鎖定的一個對象,並在該數組和通知消息中添加元素,即應該顯示一個對象。 但是這里所有三個對象(即sample,sample1,sample2)都得到通知並在數組中添加元素。 我不知道為什么它會以這種方式執行。 如果我已經三遍調用notifyAll方法,那么輸出應該與上述格式相同。我希望輸出與前一種情況相同(我使用arr.notify()方法獲得的輸出)。

誰能幫我解決這個問題...。

第二個輸出正確。 您對此進行的理解是錯誤的。

3個對象正在等待arr ,而不僅僅是一個。 我認為這解釋了調用notifyAll時的輸出。

您可能會問這種等待來自何處?

在每個樣本sample1,sample2線程中,您都有一個同步塊來獲取對arr鎖定。 因此,該塊一次只能執行一個,這就是您獲得鎖時的期望。 但是,當您致電wait ,將釋放對arr的鎖定。 因此,在sample-1釋放鎖定之后,sample-2進入同步塊。

wait文檔中:

此方法使當前線程(稱為T)將自己置於該對象的等待集中,然后放棄對該對象的任何和所有同步聲明。 出於線程調度目的,線程T被禁用,並且在發生以下四種情況之一之前處於休眠狀態:

  • 其他一些線程為此對象調用notify方法,並且線程T偶然被選擇為要喚醒的線程。
  • 其他一些線程為此對象調用notifyAll方法。
  • 其他一些線程中斷線程T。
  • 指定的實時量或多或少已經過去。 但是,如果超時為零,則不考慮實時,線程只是等待直到通知。

然后將線程T從該對象的等待集中刪除,並重新啟用線程調度。 然后,它以通常的方式與其他線程競爭在對象上進行同步的權利。 一旦它獲得了對象的控制權,它對對象的所有同步聲明就會恢復到原樣-即,恢復到調用wait方法時的情況。 然后,線程T從調用wait方法返回。 因此,從wait方法返回時,對象和線程T的同步狀態與調用wait方法時的狀態完全相同。

暫無
暫無

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

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