Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8279376

ConditionObject#signalAll only completed transfer op not waking up threads

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      hi team,
      I have a question that signalAll function just transfer nodes that exists in the condition queue to CLH queue. However I found that AQS depeneds on unparkSuccessor to wake up thread one by one.
      So , is there a puzzle or misunderstanding to learn that signalAll used to wake up all threads in condition queue.

      We usually use Object.notifyAll compared to AQS.signalAll . Most of us think that signalAll will do two things:
      1. transfer nodes from condition queue to CLH.
      2. wake up those threads corresponded to nodes.

      However , I just found one done. Because signalAll use transferForSignal op one by one.

      Maybe I lose something or misunderstand signalAll.
      Sincerely look forward to receiving else from you.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1.Setup one breakpoint on System.out.println line in Thread3 run function.
      2.Debug Application
      3.Use jstack or [get thread dump] in idea's Debug pannel
      4.You will find Thead1, Main, Thread2 are all waiting status.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      After completing signalAll() , thread1 and thread2 are Runnable status.
      ACTUAL -
      thread1 and thread2 are waiting status.

      ---------- BEGIN SOURCE ----------
      Main Class:

      public class Application {

         private static ReentrantLock _lock = new ReentrantLock();
         private static Condition _cond = _lock.newCondition();

          public static void main(String[] args) throws InterruptedException {

              Thread thread1 = new Thread(new Thread1(_lock,_cond),"thread1");
              Thread thread2 = new Thread(new Thread2(_lock,_cond),"thread2");
              Thread thread3 = new Thread(new Thread3(_lock,_cond),"thread3");

              thread1.start();
              thread2.start();
              thread3.start();

              thread1.join();
              thread2.join();
              thread3.join();

              System.out.println("main end");

          }

      }

      public class Thread1 implements Runnable{

          private ReentrantLock _lock;

          private Condition _cond;

          public Thread1(ReentrantLock _lock, Condition _cond) {
              this._lock = _lock;
              this._cond = _cond;
          }

         
          @Override
          public void run() {

              String threadName = Thread.currentThread().getName();
              System.out.println(String.format("%s----,启动",threadName));

              LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));

              _lock.lock();

              System.out.println(String.format("%s----,wait前",threadName));

              try {
                  _cond.await();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }

              System.out.println(String.format("%s----,wait后,time:%d",threadName,System.currentTimeMillis()));

              _lock.unlock();


          }
      }

      public class Thread2 implements Runnable{

          private ReentrantLock _lock;

          private Condition _cond;

          public Thread2(ReentrantLock _lock, Condition _cond) {
              this._lock = _lock;
              this._cond = _cond;
          }

        
          @Override
          public void run() {

              String threadName = Thread.currentThread().getName();
              System.out.println(String.format("%s----,启动",threadName));

              LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(2));

              _lock.lock();

              System.out.println(String.format("%s----,wait前",threadName));

              try {
                  _cond.await();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }

              System.out.println(String.format("%s----,wait后,time:%d",threadName,System.currentTimeMillis()));

              _lock.unlock();


          }
      }

      public class Thread3 implements Runnable{


          private ReentrantLock _lock;

          private Condition _cond;

          public Thread3(ReentrantLock _lock, Condition _cond) {
              this._lock = _lock;
              this._cond = _cond;
          }



        
          @Override
          public void run() {

              String threadName = Thread.currentThread().getName();
              System.out.println(String.format("%s----,启动",threadName));

              LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(3));

              _lock.lock();

              System.out.println(String.format("%s----,signal前",threadName));

              _cond.signalAll();

              System.out.println(String.format("%s----,signal后",threadName));

              _lock.unlock();




          }
      }

      ---------- END SOURCE ----------

            psandoz Paul Sandoz
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: