This discussion is archived
1 2 Previous Next 24 Replies Latest reply: Feb 17, 2013 12:47 AM by EJP Go to original post RSS
  • 15. Re: Can a Thread wake up itself?
    Kayaman Guru
    Currently Being Moderated
    teasp wrote:
    OK, you do not need to go through the code, but please point out one flawed part you have seen, just as EJP did. Thank you very much.
    I'll point out your flawed assumption that a thread can wake itself up by doing a notify() before a wait(). That would be against the spec. Do you think you're right, or the specification?
  • 16. Re: Can a Thread wake up itself?
    801554 Newbie
    Currently Being Moderated
    So you think spec is always right? I beg you teach me, according to the spec, what result I can expect from Toolkit.getDefaultToolkit().getLockingKeyState(KeyEvent.VK_CAPS_LOCK)? It is irrelevant to concurrency, but I hope you will do experiment on it.
  • 17. Re: Can a Thread wake up itself?
    801554 Newbie
    Currently Being Moderated
    It is one assumption indeed. I think when ++i in trd1 is being executing, trd2 is in waiting state, as a result, ++i should be safe. Please ignore the first time ++i is executed, at that time, trd2 is not started yet.

    If ++i is not safe here, why the result goes to fine(no output) while I do not comment out the two Thread.sleep(1) statements? I run it for hours!
  • 18. Re: Can a Thread wake up itself?
    EJP Guru
    Currently Being Moderated
    So you think spec is always right?
    The specification is always right, by definition. If the implementation doesn't agree with the specification, it is the implementation that isn't right. Except in the rare cases where the spec may need clarification of course, but this isn't one of those cases.
    It is one assumption indeed.
    Even one false assumption is sufficient to invalidate your reasoning.
    I think when ++i in trd1 is being executing, trd2 is in waiting state, as a result, ++i should be safe.
    Both threads can execute their parts before the synchronized block concurrently, at least the first time.
    Please ignore the first time ++i is executed, at that time, trd2 is not started yet.
    You don't know that. That's just another, false, assumption.

    Don't write code like this and you won't get any nasty surprises.
  • 19. Re: Can a Thread wake up itself?
    baftos Expert
    Currently Being Moderated
    We are on a tangent with this i++. Just synchronize accesses to i and see if your 'self-awakening' thread still happens.
    For me, after running 4 processes with your exact posted code the whole night, it did not happen. Win 7, Java 7.
    What is your environment? Maybe you run a buggy VM?
  • 20. Re: Can a Thread wake up itself?
    EJP Guru
    Currently Being Moderated
    Good observation. In fact we're on a tangent with the whole second thread business. All that is needed to establish or disprove the case is one thread with a timed wait. If the thread wakes up without a wait timeout, it has awoken itself. If not, not.
  • 21. Re: Can a Thread wake up itself?
    801554 Newbie
    Currently Being Moderated
    Thank you for running the code on your environment. It is not a surprise to see different behavior in Java Cocurrency. It possibilly is a OS-related issue. I run 3 process on another computer, and did not get any output, the environment is 2 cpus, Java 5, Win 7. The environment that can produce weird output is : Win XP, Java 6, 2 cpus, standard VM.

    Edited by: teasp on 2013-2-16 上午12:49

    Edited by: teasp on 2013-2-16 上午12:59
  • 22. Re: Can a Thread wake up itself?
    801554 Newbie
    Currently Being Moderated
    I think you are right. The root cause should be: spurious wakeup: a Thread can wake up from wait() state without being notified or interrupted. I didn't know this before. The spec is right: As in the one argument version, interrupts and spurious wakeups are possible, and this method(wait()) should always be used in a loop.

    Thank you, Thank all of you disscussed in this thread!
  • 23. Re: Can a Thread wake up itself?
    801554 Newbie
    Currently Being Moderated
    I changed the code to below, and get spurious wakeup easily when run 2 processes at the same time:

    public class VisibilityTest {
         public static volatile boolean condition = false;
         public static /*volatile*/ int i = 0;
         private static Object lock = new Object();
         public static Thread trd1;
         public static Thread trd2;

         public static void main(String args[]) throws InterruptedException {
              trd1 = new Thread(new Runnable() {
                   public void run() {
                        while (true) {
                             ++i; //it is not atomic, but no other thread access i at this time.
                             condition = false;
                             synchronized(lock) {
                                  lock.notify();
                                  try {
                                       int count = 0;
                                       while (condition == false) {
                                            if (++count > 1) {
                                                 System.out.println("trd1 count=" + count + "; trd2's state is " + trd2.getState());
                                            }
                                            lock.wait();
                                       }
                                  } catch (InterruptedException e) {
                                       e.printStackTrace();
                                  }
                             }
                        }
                   }
              });
              
              trd2 = new Thread(new Runnable() {
                   private int j = 0;
                   public void run() {
                        while (true) {
                             int k = i - j;
                             if (k != 1) {
                                  System.out.println("I see you : j="+j + "; k=" + k);
                             }
                             j = i;
                             
                             condition = true;
                             synchronized(lock) {
                                  lock.notify();
                                  try {
                                       int count = 0;
                                       while (condition == true) {
                                            if (++count > 1) {
                                                 System.out.println("trd2 count=" + count + "; trd1's state is " + trd1.getState());
                                            }
                                            lock.wait();
                                       }
                                  } catch (InterruptedException e) {
                                       e.printStackTrace();
                                  }
                             }
                        }
                   }
              });
              
              trd1.start();
              Thread.sleep(10);
              trd2.start();
         }
    }


    output is like :

    trd1 count=2; trd2's state is BLOCKED
    trd2 count=2; trd1's state is BLOCKED
    trd2 count=2; trd1's state is BLOCKED
    trd2 count=2; trd1's state is BLOCKED

    Edited by: teasp on 2013-2-17 上午12:23
  • 24. Re: Can a Thread wake up itself?
    EJP Guru
    Currently Being Moderated
                             ++i; //it is not atomic, but no other thread access i at this time.
    That comment continues to be untrue.

    There is certainly such a thing as spurious wakeup, and your code is certainly flawed from that point of view, but you are continuing to make false assumptions as well. The standard idiom for using wait/notify in Java is as follows:
    while (!condition)
    {
      object.wait();
      condition = false;
    }
    
    // ...
    
    condition = true;
    object.notify();
1 2 Previous Next

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points