Download presentation
Presentation is loading. Please wait.
Published byMark Golden Modified over 9 years ago
1
Universidad Nacional de Colombia Facultad de Ingeniería Departamento de Sistemas ertificación en AVA
2
7. THREADS Objectives Thread Fundamentals Controlling Threads Monitors, wait() and notify()
3
Objectives Write code to define, instantiate, and start new threads using both java.lang.Thread and java.lang.Runnable Recognize conditions that might prevent a thread from Recognize conditions that might prevent a thread fromexecuting Write code using synchronized, wait, notify, and notifyAll Write code using synchronized, wait, notify, and notifyAll to protect against concurrent access problems and to communicate between threads. Define the interaction between threads and between threads and object locks when executing synchronized, wait, notify, or notifyAll
4
Introduction Threads area java’s way of making a single JVM look like many machines, all running at the same time The CPU switches among the JVM’s various projects to give the impression of multiple CPUs
5
Thread fundamentals 1.The Java.lang.Thread class 2.The Java.lang.Object class 3.The Java language and virtual machine Java’s thread support resides in Every thread corresponds to an instance of the Thread class
6
A thread can be in various states: At any moment, at most one object is executing per CPU, while others might be waiting for resources, or waiting for a chance to execute, or sleeping, or dead
7
When a thread executes, what code does it execute? What states can a thread can be in? How does a thread changes its state? In order to understand threads, you need to be able to answer these questions
8
What a thread executes thread scheduler: determines which thread is actually running on each available CPU at any given time To make a thread execute, you call its start() method (register the thread with the thread scheduler) This does not immediately cause the thread to run; it just makes it eligible to run. The thread must still contend for CPU time with all the other threads
9
When a thread gets to execute, what does it execute? The thread can execute its own run() method The thread can execute the run() method of some other object
10
1.public class CounterThread extends Thread { 2.public void run() { 3.for (int i=1; i<=10; i++) { 4. System.out.println(“Counting: ” + i) 5.} 6.} 7.} 1.CounterThread ct = new CounterThread(); 2.ct.start(); // start(), not run() Eventually the thread will execute, and at that time its run() method will be called
11
public Thread(Runnable target) When you call the thread constructor, you have to specify which object owns the run() method that you want public void run() The Runnable interface describes a single method
12
1.public class DownCounter implements Runnable { 2.public void run() { 3.for (int i=10; i>=1; i--) { 4. System.out.println(“Counting: ” + i) 5.} 6.} 7.} 1.DownCounter dc = new DownCounter(); 2.Thread t = new Thread(dc); 3.t.start(); Downcounter does not extend Thread, but it has a run() method, and it declares that it implements the Runnable interface
13
Subclass Thread.Subclass Thread. Define your run() method in the subclass Write a class that implements Runnable.Write a class that implements Runnable. Define your run() method in that class. Pass an instance of that class into your call to the Thread constructor Approaches to specifying which run() method will be executed by a thread
14
When execution ends When the run() method returns, the thread has finished its task and is considered dead Once a thread is dead, it may not be started again A dead thread continues to exist; you can still access its data and call its methods. You just cannot make it run again!! The thread methods include a method called stop(), which forcibly terminates a thread, putting it into the dead state
15
If a thread might need to be killed from another thread, you should send it an interrupt() from the killing method!!!
16
Thread states When you call start() on a thread, it does not run immediatley. It goes into a “ready-to-run” state and stays there until the scheduler moves it to the “running state” Thread states: Running the states all threads aspire toRunning the states all threads aspire to Various waiting statesVarious waiting states waiting, sleeping, suspended, blocked Ready Not waiting for anything exceptReady Not waiting for anything except the CPU the CPU Dead All doneDead All done
17
Living thread states Monitor States Suspended Ready Running Asleep Blocked
18
Thread Priorities Every thread has a priority, an integer from 1 to 10; threads with higher priority get preference over threads with lower priority The priority is considered by the thread scheduler when it decides which ready thread should execute The scheduler generally chooses the highest- priority waiting thread. There is no guarantee that the thread chosen will be the one that has been waiting the longest
19
The default priority is 5, but all newly created threads have their priority set to that of the creating thread setPriority() method: to set a thread’s priority, passing in the desired priority getPriority() method: returns a thread’s priority 1.int oldPriority=theTread.getPriority(); 2.int newPriority=Math.min(oldPriority+1, Thread.MAX_PRIORITY ); 3.theThread.setPriority( newPriority );
20
Controlling threads The art of moving threads from state to state Pathways out of the Running state YieldingYielding Suspending and then resumingSuspending and then resuming Sleeping and then waking upSleeping and then waking up Blocking and then continuingBlocking and then continuing the CPU the CPU Waiting and then being notifiedWaiting and then being notified
21
Yielding A thread can offer to move out of the virtual CPU by yielding A call to yield() method causes the currently executing thread to move to the Ready state yield() scheduled Running Ready
22
1.public void traceRays() { 2.for (int j=0; j<300; j++) { 3.for (int i=0; i<300; i++) { 4. computeOnePixel(i, j) 5.} 6. } 7.} Yielding allows a time-consuming thread to permit other threads to execute The ray-tracing thread can have its priority set like this rayTraceThread.setPriority(thread.NORM_PRIORITY-1)
23
1.public void traceRays() { 2.for (int j=0; j<300; j++) { 3.for (int i=0; i<300; i++) { 4. computeOnePixel(i, j) 5. Thread.yield(); 6.} 7. } 8.}
24
Suspending allows any arbitrary thread to make another thread un-runnable for an indefinite period of time The suspended thread becomes runnable when some other thread resumes it The effect of suspend and resume is much better implemented using wait and notify
25
Sleeping A sleeping thread passes time without doing anything and without using the CPU public static voidpublic static void sleep(long milliseconds) throws InterruptedException sleep(long milliseconds) throws InterruptedException public static voidpublic static void sleep(long milliseconds, int nanoseconds) throws sleep(long milliseconds, int nanoseconds) throws InterruptedException InterruptedException
26
A sleep call will block a thread for at least the requested time, but it might block for much longer A sleeping thread that receives an interrupt() call moves immediately into the ready state; when it gets to run, it will execute its interruptedException handler Ready Running Sleeping sleep() Time expires or interrupted scheduled The Sleeping state
27
Blocking Many methods that perform input or output have to wait for some occurrence in the outside world before they can proceed 1.try { 2.Socket sock = new Socket(“magnesium”, 5505); 3.InputStream istr = sock.getInputStream(); 4.int b = istr.read(); 5.} 6.catch (IOException ex) { 7.// Handle the exception 8.} Example: Reading from a socket
28
The Blocked State Ready Running Blocked Blocking method Blocking condition changes or interrupted scheduled
29
Monitor States Suspended Ready Running Sleep Blocked
30
Scheduling Implementations 1. Preemptive scheduling Ways for a thread to leave the running state It can cease to be ready to execute (e.g, by calling a blocking I/O method) It can get moved out of the CPU by a higher priority thread that becomes ready to execute 2. Time-sliced or round-robin scheduling A thread is only allowed to execute for a limited amount of time
31
Monitors, wait(), and notify A monitor is an object that can block and revive threads The reason for having monitors is that sometimes a thread cannot perform its job until an object reaches a certain state
32
Example: Handling requests to write to standard output 1.class Mailbox { 2.public boolean request; 3.public String message; 4.} 1.myMailbox.message = “Hello everybody.”; 2.myMailbox.request = true; A client can set a message to some value, then set a request to true
33
1.public class Consumer extends Thread{ 2.private Mailbox myMailbox; 3. 3. 4. public Consumer(Mailbox box) { 5.this.myMailbox = box; 6. } 7. 7. 8. public void run() { 9. while (true) { 10. if (myMailbox.request) { 11. System.out.println(myMailbox.message); 12. myMailbox.request = false; 13. } 14. try { 15. sleep(50); 16. } 17. catch (InterruptedException e) { } 18. } 19. } 20. }
34
Java’s monitor provides the following resources A lock for each object The synchronized keyword for accessing an object’s lock The wait(), notify(), and notifyAll() methods, which allow the object to control client threads
35
The object lock and synchronization Every object has a lock. At any moment, that lock is controlled by, at most, one single thread. The lock controls access to the object’s synchronized code A thread that wants to execute an object’s synchronized code must first attempt to acquire that object’s lock If the lock is under another thread’s control, then the attempting thread goes into the Seeking Lock state and only becomes ready when the lock becomes available
36
The Seeking lock State Ready Running Seeking lock Lock obtained scheduled Enter the synchronized code
37
Ways to mark a code as synchronized Synchronize an entire method by putting the synchronized modifer in the method’s declaration. To execute the method, a thread must acquire the lock of the object that owns the method Synchronize a subset of the a method by surrounding the desired lines of code with curly brackets ({}) and inserting the synchronized(someObject) expression before the opening curly
38
1.class Mailbox { 2. private boolean request; 3. private String message; 4. 4. 5. public synchronized void storeMessage(String message) { 6. request = true; 7. this.message = message; 8. } 9. 9. 10. public synchronized String retrieveMessage() { 11. request = false; 12. return message; 13. } 14.}
39
wait() and notify() Provide a way for a shared object to pause a thread when it becomes unavailable to that thread, and to allow the thread to continue when appropriate The threads themselves never have to check the state of the shared object An object that controls its client threads in this manner is known as a monitor Monitor: any object that has some synchronized code
40
Both wait() and notify() must be called in synchronized code A thread that calls wait releases the virtual CPU; at the same time, it releases the lock. It enters a pool of waiting threads, which is managed by the object whose wait() method got called. Every object has such a pool
41
1.public synchronized String retrieveMessage() { 2. while (request == false) 3. try { 4. wait(); 5. } catch(InterruptedException e) {} 6. } 7. request = false; 8.return message; 9.} myMailbox.retrieveMessage(); A message-consuming thread calling this method
42
The Monitor States Ready Running Seeking lock Lock obtained scheduled Enter the synchronized code Waiting notify() or notifyAll() timeout or interrupt wait
43
1.public synchronized void storeMessage(String message) { 2. this.message = message; 3. request = true; 4. notify(); 5.} Revised storeMessage()
44
1.class Mailbox { 2. private boolean request; 3. private String message; 4. 4. 5. public synchronized void storeMessage(String message) { 6. while(request == true) { // No room for another message 7. try { 8. wait(); 9. } catch (InterruptedException e) {} 10. } 11. request = true; 12. this.message = message; 13. notify(); 14. } 15. 15. 16. public synchronized String retrieveMessage() { 17. while(request == false) { // No message to retrieve 18. try { 19. wait(); 20. } catch (InterruptedException e) {} 21. } 22. request = false; 23. notify(); 24. return message; 25. } 26.}
45
Main points about wait() The calling thread gives up the CPU The calling thread gives up the lock The calling thread goes into the monitor’s waiting pool
46
Main points about notify() One thread gets moved out of the monitor’s waiting pool and into the Ready The thread that was notified must re-acquire the monitor’s lock before it can proceed
47
Beyond the pure model The notify method is not precise: You cannot specify which thread is to be notified A thread might alter the monitor’s state in a way that is useless to the particular thread that gets notified. In such a case, the monitor’s methods should take two precautions Always check the monitor’s state in a while loop rather than an if statement After changing the monitor’s state, call notifyAll() rather than notify()
48
You should not do the following: public synchronized void mixedUpMethod() { if ( i 4.3f || message.equals(“UH-OH”) { try { wait(); } try { wait(); } catch (InterruptedException e) { } catch (InterruptedException e) { } } // proceed in a way that changes state, and then... notify();}
49
The solution is to change mixedUpMethod() as follows public synchronized void mixedUpMethod() { while ( i 4.3f || message.equals(“UH-OH”) { try { wait(); } try { wait(); } catch (InterruptedException e) { } catch (InterruptedException e) { } } // proceed in a way that changes state, and then... notifyAll();}
50
Strange ways to synchronize Synchronizing on the lock of a different object Synchronizing on the lock of a class class StrangeSync { Rectangle rect=new Rectangle(11, 13, 1100, 1300 ); void doit() { int x=504; int y=x/3; rect.width -= x; rect.height -= y; }}
51
class StrangeSync { Rectangle rect=new Rectangle(11, 13, 1100, 1300 ); void doit() { int x=504; int y=x/3; synchronized(rect) { rect.width -= x; rect.width -= x; rect.height -= y; rect.height -= y;} }} The following code synchronizes on the lock of some arbitrary object
52
To synchronize an entire method, using the lock of the object that owns the method. Put the synchronized keyword in the method’s declaration To synchronize part of a method, using the lock of an arbitrary object. Put curly brackets around the code to be synchronized, preceded by synchronized(theArbitraryObject) To synchronize part of a method, using the lock of the object that owns that methods. Put curly brackets around the code to be synchronized, preceded by synchronized(this)
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.