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

5.0 "synchronized" method causes starvation

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P2 P2
    • None
    • 5.0u2
    • hotspot
    • x86
    • solaris_2.5.1

      In 5.0, if using "synchronized" feature, scheduling algorithm will favor new threads, starving others in the process. This behavior is total different than in 1.4. This causes problems in some of our system since some threads never got served and starved.

      Tested on 1.5.0_05-b03 and 1.5.0_02-b09.

      Following is the simple program that will print out which threads got served first. Compile with 1.4 and 5.0 to see the difference.

      Source code (TestThreading.java):
      #####################################################################
      public class TestThreading {
          
          public static void main(String[] args) throws Exception {
              Thread threads[] = new Thread[100];
              int stats[] = new int[100];

              Thread stat_thread= new Thread(new Stat(stats));
              stat_thread.start();

              for (int i = 0; i < 100; i++) {
                  threads[i] = new Thread(new Driver(i, stats));
                  threads[i].start();
              }

              for (int i = 0; i < 100; i++) {
                  threads[i].join();
              }
              stat_thread.interrupt();
          }

          public static class Stat implements Runnable {
              private int[] stats;

              public Stat(int[] stats) {
                  this.stats = stats;
              }
              
              public void run() {
                  try{
                      while (true) {
                          Thread.sleep(20000);
                          printTopThreads(10);
                      }
                  }
                  catch(Exception e){
                    
                  }
              }

              private void printTopThreads(int rank) {
                  int[] temp = new int[100];
                  System.arraycopy(stats, 0, temp, 0, 100);

                  int max = 0;
                  int idx = 0;

                  for(int i=0; i<rank; i++) {
                      max = 0;
                      for(int j=99; j>=0; j--) {
                          if(temp[j] >= max) {
                              max = temp[j];
                              idx = j;
                          }
                      }
                      System.out.print("[");
                      if(idx <10)
                          System.out.print(" ");
                      System.out.println( idx + "] - " + max);
                      temp[idx] = -1;
                  }
                  System.out.println("**********************************************");
              }
          }
                       
          
          public static class Driver implements Runnable {
              private int id;
              private int[] stats;
              
              public Driver(int id, int[] stats) {
                  this.id = id;
                  this.stats = stats;
              }
              
              public void run() {

                  BottleNeck b = BottleNeck.getInstance();
                  for(int i = 0; i < 50; i++) {
                      b.doSomething(id);
                      stats[id] ++;
                      try {
                          Thread.sleep(25);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }

              }
          }
          
          public static class BottleNeck {
              private static BottleNeck instance = new BottleNeck();
              
              public static BottleNeck getInstance() {
                  return instance;
              }
              
              public synchronized void doSomething(int id) {
                  try {
                      //System.out.println("Thread " + id);
                      Thread.sleep(300);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          }

      }
      #####################################################################

            dice Dave Dice
            mmma Marvin Ma (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: