Thread priorities are used by the thread scheduler to decide when each thread should be allowed to run. In theory, higher-priority threads get more CPU time than lower-priority threads. In practice, the amount of CPU time that a thread gets often depends on several factors besides-its priority. (For example, how an operating system implements multitasking can affect the relative availability of CPtJ time.) A "
higher-priority thread can also preempt a lower-priority one. For instance, when a lower-priority thread is running and a higher-priority thread resumes (from sleeping or waiting on 1/0, for example), it will preempt the lower-priority thread. In theory, threads of equal priority should get equal access to the CPU. But you, need to be careful, Remember, Java is designed to work in a wide range of environments, Some of those environments implement multitasking fundamentally differently than others. For safety, threads that share the same priority should yield control once in a while. This ensures that all threads have a chance to run under a nonpreemptive operating system. In practice, even in non preemptive environments, most threads still get a chance to run, because most threads inevitably encounter some blocking situation, such as waiting'for I/O. When this happens. the blocked thread is suspended and other threads can run. But, if you want smooth multithreaded execution, you are better off n9.t relying on this. Also, some types of tasks are , CPU-intensive. Such threads dominate the CPU. For these types of threads, you want to yield control occasionally, SI) that other threads can run.
To set a thread's priority. use the setPriority( ) method, which is a member of Thread. This is its general form:
final void setPriority(int level)
Here, level specifies the new priority setting for the calling thread. The value of lcoc! must be within the range MIN_PRIORITY and MAX_PRIORITY. Currently. these , values are 1 and 10, respectively. To return a thread to default priority, specify ,NORM_PRIORITY, which is currently 5. These priorities are defined as final variables within Thread. You.can obtain the current priority setting by calling the setPriority() method of Thread, shown here:
final int getPriority( )
Implementations of Java may have radically different behavior when it comes to scheduling. The Windows 95/9B/NT version works, more or less, as you would expect. However, other versions may work quite differently. Most of the inconsistencies arise when you have threads that are relying on preemptive behavior, instead of cooperatively giving up CPU time. The safest way to obtain predictable, cross-platform behavior with. Java is to use 'threads that voluntarily give up control of the CPU.The following example demonstrates two threads at different priorities, which do not run on a preemptive platform in the same way as they run on a nonpreemptive platform. One thread is set two levels above the normal priority, as defined, by Thread.NORM PRIORITY, and the other is set to two.levels below it. The thread are started and allowed to run for ten seconds.Each thread executes a loop, counting the number of iterations. After ten seconds, the main thread stops both threads. The number of times that each thread made it through the Joop is then displayed.The output of this program, sh~wn, as follows when run under Windows 98 indicates that the threads did context switch, even though neither voluntarily yielded the CPU nor blocked for 1/0. The higher-priority thread got approximately, 90 percent of the CPU time
Low-priority thread: 4400112
High-priority' thread: 589626904
Of course; the exact output produced by this program depends on the speed of your CPU and the number of other tasks running in the system. When this same program is run under a nonpreemptive system, different results will be obtained. One othernote about the preceding program. Notice that running is preceded by the keyword volatile. Although volatile is examined more carefully in the next chapter, it is used here to ensure that the value of running is examined each time the following loop iterates:
Without the use of volatile, Java is free to optimize the loop in such a way that the value of running is held in a register of the CPU and not necessarily reexamined with each Iteration. The' use of volatile prevents 'this optimization, telling Java that running may change in ways not directly apparent in the immediate code.