0

I am using a "transceiver" to send a request from the client to the server and wait for the response. I learned from [here][1] the way to communicate between two threads and wrote bellow codes:

public class ThreadEvent {

    private Object lock;
    private Object data;
    private String ntfInfo;

    public ThreadEvent() {
        data = null;
        lock = new Object();
        ntfInfo = "NONE";
    }

    public boolean await(int time) {
        synchronized (lock) {
            try {
                lock.wait(time);
                return true;
            } catch (InterruptedException ex) {
                LogManager.ex(ex);
                return false;
            }
        }
    }

    public void signal() {
        synchronized (lock) {
            ntfInfo = (new Throwable()).getStackTrace()[1].getMethodName() + "@"
                    + (new Throwable()).getStackTrace()[1].getClassName() + "@"
                    + "line" + (new Throwable()).getStackTrace()[1].getLineNumber() + "@"
                    + (new Throwable()).getStackTrace()[1].getFileName();
            lock.notify();
        }
    }

    public synchronized void putData(Object data) {
        this.data = data;
    }

    public synchronized Object takeData() {
            Object res = data;
            data = null;
            return res;
    }

    public String takeNtfInfo() {
        String info = ntfInfo;
        ntfInfo = "NONE";
        return info;
    }
}

I found sometimes the send-and-wait thread was not always been notified by the response, nor been interrupted, (as per my understanding) but was awaked from the wait by some mysterious "thing". Here is the log:

1460717223039:DEBUG:1   starting... @<init>@wsclientapp.GUIManager@line57@GUIManager.java
1460717229475:DEBUG:2   transceive()@line30@WSTransceiver.java
1460717229735:DEBUG:3   forward()@line69@WSTransceiver.java
1460717229739:DEBUG:4   transceive(ivoked by: forward@wsclientapp.util.WSTransceiver@line73@WSTransceiver.java)@line42@WSTransceiver.java
1460717229750:DEBUG:5   transceive()@line30@WSTransceiver.java
1460717229768:DEBUG:6   forward()@line69@WSTransceiver.java
1460717229768:DEBUG:7   transceive(ivoked by: forward@wsclientapp.util.WSTransceiver@line73@WSTransceiver.java)@line42@WSTransceiver.java
1460717229770:DEBUG:8   transceive()@line30@WSTransceiver.java
1460717234771:DEBUG:9   transceive(ivoked by: NONE)@line42@WSTransceiver.java

You may see line2/3/4 is a transaction, and line5/6/7 is another transaction, but line8/9 shows the problem. If the transceive was awaked by someone, it should print the name of the thread, or if it's been interrupted, it should print the exception stack by the LogManager.ex(ex). But it didn't. What I did wrong?

  • The server is also on my PC, so you can see the response time was pretty short. but log line8/9 showed transceiver() was awaken immediately which is the abnormal thing. – howToDeleteMyAccount Apr 15 '16 at 13:37
  • There is a lengthy discussion on this topic here: http://stackoverflow.com/questions/1050592/do-spurious-wakeups-actually-happen – NAMS Apr 15 '16 at 13:45

1 Answers1

0

When you call notify() only a thread which is waiting will be notified. If the threads are doing something else, the notify is lost.

When you call wait() it can wake spuriously.

In short;

  • only notify after a state change.
  • only wait in a while loop where you check that state check before waiting.
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • my issue is the waiting thread WSTransceiver.transceive(DataPackage package) sometimes was wake up not by the notification from WSTransceiver.forward(DataPackage package) but by "something else". You see I put a track on the notifier/caller's info in the ThreadEvent.signal() but caught nothing. – howToDeleteMyAccount Apr 15 '16 at 16:13
  • 1
    I finally can realize that the difference between 1460717234771(log line9) and 1460717229770(log line8) is actually 5 seconds so this is a network timeout due to the ongoing file transfer in the same link. so this is solved, nothing mysterious here. – howToDeleteMyAccount Apr 16 '16 at 07:23