|
Yielding
If you know that you’ve accomplished what you need to in your run( ) method, you can give a hint to the thread scheduling mechanism that you’ve done enough and that some other thread might as well have the CPU. This hint (and it is a hint—there’s no guarantee your implementation will listen to it) takes the form of the yield( ) method.
We can modify the preceding example by yielding after each loop:
//: c13:YieldingThread.java
// Suggesting when to switch threads with yield().
import com.bruceeckel.simpletest.*;
public class YieldingThread extends Thread {
private static Test monitor = new Test();
private int countDown = 5;
private static int threadCount = 0;
public YieldingThread() {
super("" + ++threadCount);
start();
}
public String toString() {
return "#" + getName() + ": " + countDown;
}
public void run() {
while(true) {
System.out.println(this);
if(--countDown == 0) return;
yield();
}
}
public static void main(String[] args) {
for(int i = 0; i < 5; i++)
new YieldingThread();
monitor.expect(new String[] {
"#1: 5",
"#2: 5",
"#4: 5",
"#5: 5",
"#3: 5",
"#1: 4",
"#2: 4",
"#4: 4",
"#5: 4",
"#3: 4",
"#1: 3",
"#2: 3",
"#4: 3",
"#5: 3",
"#3: 3",
"#1: 2",
"#2: 2",
"#4: 2",
"#5: 2",
"#3: 2",
"#1: 1",
"#2: 1",
"#4: 1",
"#5: 1",
"#3: 1"
}, Test.IGNORE_ORDER + Test.WAIT);
}
} ///:~
By using yield( ), the output is evened up quite a bit. But note that if the output string is longer, you will see output that is roughly the same as it was in SimpleThread.java (try it—change toString( ) to put out longer and longer strings to see what happens). Since the scheduling mechanism is preemptive, it decides to interrupt a thread and switch to another whenever it wants, so if I/O (which is executed via the main( ) thread) takes too long, it is interrupted before run( ) has a chance to yield( ). In general, yield( ) is useful only in rare situations, and you can’t rely on it to do any serious tuning of your application.
|
|