This section provides a tutorial example on how to measuring CPU execution time allocated to threads with different setPriorities.
Question: If there are 5 application programs running on a single CPU system,
and there 5 threads running in each of the 5 running
application programs, how all the 25 threads get executed simultaneously on that
one CPU?
The answer is that those 25 threads do not get executed simultaneous at any
given instance of time. They get executed one at a time in turns to share
the processing time of the single CPU. The following simple example illustrates
how the processing time can be shared by multiple threads.
Assuming that:
The operating system is designed to execute the running application program one
at a time in turns. For each turn, the selected application get executed for
only 1 millisecond.
If an application program gets executed, it will execute the running threads one
at a time in turns. For each turn, the selected thread gets executed for only
0.01 millisecond.
There are 5 threads running in each of the 5 running application programs.
The times spend on switch threads and application program in the CPU are
ignorable.
If we let the system runs for 0.1 second, each application program will be executed
20 times for a total time of 20 milliseconds, and each thread will be executed
400 times for a total time of 4 milliseconds. So, for a fraction of a second
(1/10 second), all threads in all applications programs will be executed for about
4 milliseconds. This will make you feel like all threads get executed simultaneously.
Now let's use the following program to see how each thread is getting its share
of the CPU time:
/**
* RacingThread.java
* Copyright (c) 2002 by Dr. Herong Yang
*/
import java.util.*;
class RacingThread extends Thread {
private static final long s_maxi = 1000000; // maximum number of steps
private static final int t_maxi = 5; // maximum number of threads
private static long[] t_done = new long[t_maxi];
private static int t_last = -1; // index of the last thread
private int t_indx;
private static int n_prime = 0;
public static void main(String[] a) {
System.out.println("Priority: (min, norm, max) = ("+
Thread.MIN_PRIORITY+", "+
Thread.NORM_PRIORITY+", "+
Thread.MAX_PRIORITY+")");
long start_time = new Date().getTime();
for (int i=0; i<t_maxi; i++) {
RacingThread t = new RacingThread();
if (i==0) t.setPriority(Thread.MIN_PRIORITY);
else if (i==1) t.setPriority(Thread.NORM_PRIORITY);
else t.setPriority(Thread.MAX_PRIORITY);
t.start();
}
System.out.print("Threads: ");
for (int i=0; i<t_maxi; i++) {
System.out.print(i+" ");
}
System.out.print("Time");
while(true) {
try {
sleep(100);
} catch (InterruptedException e) {
System.out.println("Interrupted.");
}
System.out.print("\n Steps: ");
for (int i=0; i<t_maxi; i++) {
System.out.print(t_done[i]+" ");
}
System.out.print((new Date()).getTime()-start_time);
}
}
public RacingThread() {
t_last++;
t_indx = t_last;
t_done[t_indx] = 0;
}
public void run() {
for (long s=0; s<s_maxi; s++) {
int n = 0;
for (int i=3; i<100; i++) {// keep it busy for some time
boolean is_prime = true;
for (int j=2; j<i; j++) {
is_prime = (i%j>0);
if (!is_prime) break;
}
if (is_prime) n++;
}
n_prime = n;
t_done[t_indx] = s;
}
}
}
Notes on the program design:
5 sub-threads are created to do the same piece of work at each step. Steps are
repeated for 1000000 times.
That same piece of work is to count how many prime numbers are there under
100.
The first sub-thread is given the lowest priority, the second sub-thread is given
the medium priority, and the rest 3 sub-threads are given the highest priority.
Each sub-thread is recording the number of steps it has finished so far at the
end of each step.
The main thread is repeatedly checking the recording array to see the
execution progress of each sub-threads.
The elapse time in milliseconds is also reported each time the main thread
is checking the recording array.
Each sub-thread is identified by an index number given in the constructor with
the help of a static variable: t_last.
The static variable, n_prime, is updated by all 5 sub-threads repeatedly with
the same value. I don't give any statement to print out the value of n_prime
to verify the accuracy, but I did check the correctness of my prime number
counting algorithm in a separate program.
The main thread will never end by itself. You need to press Ctrl-C to terminate
the program.
See the next section for execution output of this program.