Page 105 - DCAP103_Principle of operating system
P. 105
Principles of Operating Systems
Notes Ending task: Task 2 at 00:04:38:380 after 8056 milliseconds
Ending task: Task 0 at 00:04:38:502 after 8168 milliseconds
Let us look at this output. Notice that the last thread we created and started (Task 2) was the
first one that printed its first output. However, all threads started within 20 milliseconds of each
other. The actual calculation took about eight seconds for each thread, and the threads ended
in a different order than they started in. In particular, even though Task 2 started first, it took
349 milliseconds longer to perform the same calculation as Task 1 and finished after Task 1.
Generally, we had expect to see similar output on almost any Java virtual machine running
on almost any platform: the threads would start at almost the same time in some random
order, and they would end in a (different) random order after having run for about the
same amount of time. Certain virtual machines and operating systems, however, would
produce this output:
Starting task: Task 0 at 00:04:30:324
Ending task: Task 0 at 00:04:33:052 after 2728 milliseconds
Starting task: Task 1 at 00:04:33:062
Ending task: Task 1 at 00:04:35:919 after 2857 milliseconds
Starting task: Task 2 at 00:04:35:929
Ending task: Task 2 at 00:04:37:720 after 2791 milliseconds
The total here takes about the same amount of time, but now they have run sequentially: the
second task did not begin to execute until the first task was finished. Another interesting fact
about this output is that each individual task took less time than it did previously.
3.7.1 Priority-based Scheduling
In each of these examples, multiple threads compete for time on the CPU. When multiple threads
want to execute, it is up to the underlying operating system to determine which of those threads
are placed on a CPU. Java programs can influence that decision in some ways, but the decision
is ultimately up to the operating system.
A Java virtual machine is required to implement a preemptive, priority-based scheduler among
its various threads. This means that each thread in a Java program is assigned a certain priority,
a positive integer that falls within a well-defined range. This priority can be changed by the
developer. The Java virtual machine never changes the priority of a thread, even if the thread has
been running for a certain period of time. The priority value is important because the contract
between the Java virtual machine and the underlying operating system is that the operating
system must generally choose to run the Java thread with the highest priority. That is what
we mean when we say that Java implements a priority-based scheduler. This scheduler is
implemented in a preemptive fashion, meaning that when a higher-priority thread comes
along, that thread interrupts (preempts) whatever lower-priority thread is running at the
time. The contract with the operating system, however, is not absolute, which means that the
operating system can sometimes choose to run a lower-priority thread. Java’s requirement
for a priority-based, preemptive scheduling mechanism maps well to many operating
systems. Solaris, the various Windows operating systems, Linux, and most other operating
systems on desktop computers and servers all provide the support for that kind of thread
scheduling. Certain operating systems, particularly those on specialized devices and on
smaller, handheld devices, do not provide that level of scheduling support; Java virtual
98 LOVELY PROFESSIONAL UNIVERSITY