繁体   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