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();
}
}
}
}
#####################################################################
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();
}
}
}
}
#####################################################################
- duplicates
-
JDK-4985566 Equal priority threads not timslicing properly in Linux
-
- Closed
-
- relates to
-
JDK-6383015 Biased thread scheduling in Java 5.0 on Linux and Solaris
-
- Closed
-
-
JDK-6541879 Thread.sleep() within a synchronized block influences subsequent lock aquisition
-
- Closed
-