1 / 52

Universidad Nacional de Colombia Facultad de Ingeniería Departamento de Sistemas

C. ertificación en. J. AVA. Universidad Nacional de Colombia Facultad de Ingeniería Departamento de Sistemas. Objectives Thread Fundamentals Controlling Threads Monitors, wait() and notify(). 7. THREADS. Objectives. Write code to define, instantiate, and start new threads using

kimo
Télécharger la présentation

Universidad Nacional de Colombia Facultad de Ingeniería Departamento de Sistemas

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C ertificación en J AVA Universidad Nacional de Colombia Facultad de Ingeniería Departamento de Sistemas

  2. Objectives • Thread Fundamentals • Controlling Threads • Monitors, wait() and notify() 7. THREADS

  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 • executing • 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. 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 Introduction

  5. Every thread corresponds to an instance of the Thread class Thread fundamentals Java’s thread support resides in The Java.lang.Thread class The Java.lang.Object class The Java language and virtual machine

  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 waitingfor a chance to execute, or sleeping, or dead

  7. In order to understand threads, you need to be able to answer these questions • When a thread executes, what code does it execute? • What states can a thread can be in? • How does a thread changes its state?

  8. 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 What a thread executes thread scheduler: determines which thread is actually running on each available CPU at any given time

  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. public class CounterThread extends Thread { • public void run() { • for (int i=1; i<=10; i++) { • System.out.println(“Counting: ” + i) • } • } • } • CounterThread ct = new CounterThread(); • 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) public void run() When you call the thread constructor, you have to specify which object owns the run() method that you want The Runnable interface describes a single method

  12. DownCounter dc = new DownCounter(); • Thread t = new Thread(dc); • t.start(); • public class DownCounter implements Runnable { • public void run() { • for (int i=10; i>=1; i--) { • System.out.println(“Counting: ” + i) • } • } • } Downcounter does not extend Thread, but it has a run() method, and it declares that it implements the Runnable interface

  13. Subclass Thread. • Define your run() method in the subclass • 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 to • Various waiting states • waiting, sleeping, suspended, blocked • Ready Not waiting for anything except • the CPU • Dead All done

  17. Running Asleep Monitor States Suspended Blocked Ready Living thread states

  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. int oldPriority=theTread.getPriority(); • int newPriority=Math.min(oldPriority+1, • Thread.MAX_PRIORITY ); • theThread.setPriority( newPriority ); • 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

  20. Controlling threads The art of moving threads from state to state Pathways out of the Running state • Yielding • Suspending and then resuming • Sleeping and then waking up • Blocking and then continuing • the CPU • Waiting and then being notified

  21. Running Ready 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

  22. public void traceRays() { • for (int j=0; j<300; j++) { • for (int i=0; i<300; i++) { • computeOnePixel(i, j) • } • } • } rayTraceThread.setPriority(thread.NORM_PRIORITY-1) Yielding allows a time-consuming thread to permit other threads to execute The ray-tracing thread can have its priority set like this

  23. public void traceRays() { • for (int j=0; j<300; j++) { • for (int i=0; i<300; i++) { • computeOnePixel(i, j) • Thread.yield(); • } • } • }

  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 void • sleep(long milliseconds) throws InterruptedException • public static void • sleep(long milliseconds, int nanoseconds) throws • InterruptedException

  26. Running sleep() scheduled Sleeping Time expires or interrupted Ready The Sleeping state 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

  27. try { • Socket sock = new Socket(“magnesium”, 5505); • InputStream istr = sock.getInputStream(); • int b = istr.read(); • } • catch (IOException ex) { • // Handle the exception • } Blocking Many methods that perform input or output have to wait for some occurrence in the outside world before they can proceed Example: Reading from a socket

  28. Running Blocking method scheduled Blocked Blocking condition changes or interrupted Ready The Blocked State

  29. Running Sleep Monitor States Suspended Blocked Ready Monitor States

  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. class Mailbox { • public boolean request; • public String message; • } • myMailbox.message = “Hello everybody.”; • myMailbox.request = true; Example: Handling requests to write to standard output A client can set a message to some value, then set a request to true

  33. public class Consumer extends Thread{ • private Mailbox myMailbox; • public Consumer(Mailbox box) { • this.myMailbox = box; • } • public void run() { • while (true) { • if (myMailbox.request) { • System.out.println(myMailbox.message); • myMailbox.request = false; • } • try { • sleep(50); • } • catch (InterruptedException e) { } • } • } • }

  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. Running Enter the synchronized code Seeking lock scheduled Lock obtained Ready The Seeking lock State

  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. class Mailbox { • private boolean request; • private String message; • public synchronized void storeMessage(String message) { • request = true; • this.message = message; • } • public synchronized String retrieveMessage() { • request = false; • return message; • } • }

  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. myMailbox.retrieveMessage(); • public synchronized String retrieveMessage() { • while (request == false) • try { • wait(); • } catch(InterruptedException e) {} • } • request = false; • return message; • } A message-consuming thread calling this method

  42. Running Waiting Seeking lock Ready The Monitor States Enter the synchronized code wait scheduled notify() or notifyAll() timeout or interrupt Lock obtained

  43. public synchronized void storeMessage(String message) { • this.message = message; • request = true; • notify(); • } Revised storeMessage()

  44. class Mailbox { • private boolean request; • private String message; • public synchronized void storeMessage(String message) { • while(request == true) { // No room for another message • try { • wait(); • } catch (InterruptedException e) {} • } • request = true; • this.message = message; • notify(); • } • public synchronized String retrieveMessage() { • while(request == false) { // No message to retrieve • try { • wait(); • } catch (InterruptedException e) {} • } • request = false; • notify(); • return message; • } • }

  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. public synchronized void mixedUpMethod() { if ( i < 16 || f > 4.3f || message.equals(“UH-OH”) { try { wait(); } catch (InterruptedException e) { } } // proceed in a way that changes state, and then . . . notify(); } You should not do the following:

  49. public synchronized void mixedUpMethod() { while ( i < 16 || f > 4.3f || message.equals(“UH-OH”) { try { wait(); } catch (InterruptedException e) { } } // proceed in a way that changes state, and then . . . notifyAll(); } The solution is to change mixedUpMethod() as follows

  50. 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; } } Strange ways to synchronize • Synchronizing on the lock of a different object • Synchronizing on the lock of a class

More Related