| ||||
Copyright 1999 Sams Publishing |
|
Using Thread.sleep() |
As beneficial as it is for threads to go about doing their work as fast as possible, sometimes it would be useful if a thread could take a break and go to sleep for a while. In a clock application, it might be the case that the thread in charge of updating the displayed time should pause for 60 seconds at a time between the changing of the minutes displayed. A busy loop such as |
long startTime = System.currentTimeMillis(); |
long stopTime = startTime + 60000; |
while (System.currentTimeMillis() < stopTime) { |
// do nothing, but loop back |
} |
takes up a lot of processor cycles. Instead, it would be better to use the following static method on Thread |
public static native void sleep(long msToSleep) |
throws InterruptedException |
to wait for 60 seconds, like this: |
try { |
Thread.sleep(60000); |
} catch (InterruptedException x) { |
// ignore the exception |
} |
Sleeping is a much better option than using a busy loop. A sleeping thread does not use any processor cycles because its execution is suspended for the specified duration. |
The sleep() method is static and puts only the currently executing threadthe one that would be returned by Thread.currentThread() to sleep. It is not possible for a thread to put any other thread to sleep. |
The try / catch construct is necessary because while a thread is sleeping, it might be interrupted by another thread. One thread might want to interrupt another to let it know that it should take some sort of action. Later chapters further explore the use of interrupts. Here, it suffices to say that a sleeping thread might be interrupted and will throw an InterruptedException if this occurs. |
Listing 3.9 shows how sleep() can be used to slow down the action and how two threads may be inside the same method of one object at the same time. |
Listing 3.9 TwoThreadSleep.javaUsing sleep() |
1: public class TwoThreadSleep extends Thread { |
2: public void run() { |
3: loop(); |
4: } |
5: |
6: public void loop() { |
7: // get a reference to the thread running this |
8: Thread t = Thread.currentThread(); |
9: String name = t.getName(); |
10: |
11: System.out.println(just entered loop() - + name); |
12: |
13: for (int i = 0; i < 10; i++) { |
14: try { |
15: Thread.sleep(200); |
16: } catch (InterruptedException x) { |
17: // ignore |
18: } |
19: |
20: System.out.println(name= + name); |
21: } |
22: |
23: System.out.println(about to leave loop() - + name); |
24: } |
25: |
26: public static void main(String[] args) { |
27: TwoThreadSleep tt = new TwoThreadSleep(); |
28: tt.setName(my worker thread); |
29: tt.start(); |
30: |
31: // pause for a bit |
32: try { |
33: Thread.sleep(700); |
34: } catch (InterruptedException x) { |
35: // ignore |
36: } |
37: |
38: tt.loop(); |
39: } |
40: } |
The method loop() is used by both run() (line 3) and by main() (line 38) to print out all the messages. In main() , sleep() is used to delay the main threads entry into the loop() method (lines 3236). On lines 1418, sleep() is also used to slow down the iterations through the for loop. Listing 3.10 shows sample output from a particular run. |
Listing 3.10 Sample Output from TwoThreadSleep |
just entered loop() - my worker thread |
name=my worker thread |
name=my worker thread |
just entered loop() - main |
name=my worker thread |
name=main |
name=my worker thread |
name=main |
name=my worker thread |
name=main |
name=my worker thread |
name=main |
name=my worker thread |
name=main |
name=my worker thread |
name=main |
name=my worker thread |
name=main |
name=my worker thread |
about to leave loop() - my worker thread |
name=main |
name=main |
name=main |
about to leave loop() - main |
In examining the output, you notice that both threads are inside the loop() method at the same time . Yet, each thread has its own copy of the local variable name to print its proper identification. Local variables work well with multiple threads, but accessing and modifying member variables (the state of an object) with multiple threads is tricky business. You will learn more about this in Chapter 7, Concurrent Access to Objects and Variables. |
| |||
Toc |