简体   繁体   中英

Regarding threading wait/notify

I am a beginner in threading concepts in java. I have done a small program by implementing wait and notify mechanism and the coding is as follows:-

Example.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();
    }
}   
}

In the samplefunc function in samplecheck.java if i give arr.notify() i am able to get the correct output as

    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

But if arr.notifyAll() instead of arr.notify() i get the output as

    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

But according to the coding perspective even though if i give notifyAll only one object which gains lock on the array 'arr' should get executed and add elements in the array and the notification message ie) An Object is Notified should be displayed. But here all the three objects ie) sample, sample1, sample2 are getting notified and adding elements in the array. I dont know why it is executing in this manner. If i had called the notifyAll method three times then the output should be as in the above format.I want the output as same as the previous case(the output which i get using arr.notify() method).

Can anyone please help me in this issue....

The second output is correct. Your understanding of that is going on is wrong.

3 objects are waiting on arr , not only one. I think this explains the output when notifyAll is called.

You might ask where this waits come from?

In every sample, sample1, sample2 thread you have a synchronized block acquiring lock on arr . So the block should be executed only one at time, what is what you expected when you acquire lock. But when you call wait the lock on arr is released. So after sample-1 released lock, then sample-2 enters synchronized block.

From the wait documentation:

This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  • Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
  • Some other thread invokes the notifyAll method for this object.
  • Some other thread interrupts thread T.
  • The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.

The thread T is then removed from the wait set for this object and re-enabled for thread scheduling. It then competes in the usual manner with other threads for the right to synchronize on the object; once it has gained control of the object, all its synchronization claims on the object are restored to the status quo ante - that is, to the situation as of the time that the wait method was invoked. Thread T then returns from the invocation of the wait method. Thus, on return from the wait method, the synchronization state of the object and of thread T is exactly as it was when the wait method was invoked.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM