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

jstack has bug for mulithread to use reentrantlock

XMLWordPrintable

    • x86
    • linux

      ADDITIONAL SYSTEM INFORMATION :
      ava version "1.8.0_102"
      Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
      Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)

      A DESCRIPTION OF THE PROBLEM :
      when jstacking a java proess in which I use ArrayBlockingQueue as a ExecutorService's queue I found out more than one thread stop at waiting ArrayBlockingQueue#353line

        public void put(E e) throws InterruptedException {
              checkNotNull(e);
              final ReentrantLock lock = this.lock;
              lock.lockInterruptibly();
              try {
                  while (count == items.length)
                      notFull.await(); // more than one thread stop here!!!
                  enqueue(e);
              } finally {
                  lock.unlock();
              }
          }

      multi threads can not acquire lock ,so can not blocking on conditions at the same time , I doubt it is a bug of jstack.

      REGRESSION : Last worked in version 8

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      just jstack the source code I submit below

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      mulit thread can not wait at ArrayBlockingQueue#353line

      ACTUAL -
      jstack shows mulit thread can wait at ArrayBlockingQueue#353line at the same time


      ---------- BEGIN SOURCE ----------
      public static void main(String[] args) {
              NonRejectedArrayBlockingQueue queue = new NonRejectedArrayBlockingQueue<>(1, true);
              NonRejectedArrayBlockingQueue sinkWorkQueue = new NonRejectedArrayBlockingQueue<>(1, true);

              ExecutorService parseExecutorService =
                      new ThreadPoolExecutor(4, 4, 60, TimeUnit.SECONDS, queue,
                              new DriverThreadFactory("parser-thread"));
              ExecutorService sinkExecutorService =
                      new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, sinkWorkQueue,
                              new DriverThreadFactory("sinker-thread"));
              for (int i = 0; i < 10; i++) {
                  parseExecutorService.submit(() -> {
                      try {
                          System.out.println("test..." + Thread.currentThread().getName());
                          sinkExecutorService.submit(() -> {
                              System.out.println("sink test" + Thread.currentThread().getName());
                          });

                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                  });
              }

          }

      public class NonRejectedArrayBlockingQueue<E> extends ArrayBlockingQueue<E> {

          public NonRejectedArrayBlockingQueue(int capacity) {
              super(capacity);
          }

          public NonRejectedArrayBlockingQueue(int capacity, boolean fair) {
              super(capacity, fair);
          }

          public NonRejectedArrayBlockingQueue(int capacity, boolean fair, Collection<? extends E> c) {
              super(capacity, fair, c);
          }

          @Override
          public boolean offer(E e) {
              // turn offer() and add() into a blocking calls (unless interrupted)
              try {
                  put(e);
                  return true;
              } catch(InterruptedException ie) {
                  Thread.currentThread().interrupt();
              }
              return false;
          }
      }

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

      FREQUENCY : always


            fmatte Fairoz Matte
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: