260 likes | 415 Views
Chapter 7. Threads. Threads & Processes Multi Threading Class Thread Synchronized Methods Wait & Notify. Threads. A thread is a single sequential flow of control within a program. A Thread. A Program. Processes.
E N D
Chapter 7 Threads • Threads & Processes • Multi Threading • Class Thread • Synchronized Methods • Wait & Notify
Threads • A thread is a single sequential flow of control within a program. A Thread A Program
Processes • A process refers to a single sequential flow of control with its own resources. • Thread s shares the same data segment. • Also referred to as execution context or a lightweight process. Two Thread A Program
Multi threads Applications • A server providing services to others. • One thread for each client. (network server) • A real-time control computer controlling a factory. • One thread for each device that needs monitoring. • Graphical interfaces. • Create a more responsive GUI. • A separate thread to react to user events. • A separate thread to do intense computation.
MultiThreaded Code in Java • Subclassing Thread class and overriding runPublic class SimpleThread extends Threads { public SimpleThread(String str){super(str);} public void run() { for (int i = 0; i < 10; i++) { System.out.println(i + " " + getName()); try { sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { } } System.out.println("DONE! " + getName()); } … }
Running it public static void main (String [ ] a) {new SimpleThread("Jamaica").start();new SimpleThread("Fiji").start(); } 0 Jamaica0 Fiji1 Jamaica1 Fiji2 Jamaica3 Jamaica2 Fiji4 Jamaica3 Fiji5 Jamaica4 Fiji5 Fiji 6 Jamaica6 Fiji7 Jamaica7 Fiji8 Fiji9 Fiji8 JamaicaDONE! Fiji9 JamaicaDONE! Jamaica
Implementing Runnable • Most times you need to subclass a class other than thread. • applet • Implement runnable • implement runmethod • create object • create a new Thread using the constructor that expects a runnable object • start the thread
Another Version • Implementing runnablePublic class SimpleRun implements Runnable { public void run() { for(int i = 0; i < 10; i++){ System.out.println(i + " " + Thread.currentThread().getName()); try {Thread.sleep((int)(Math.random()*1000)); }catch (InterruptedException e) { } } System.out.println("DONE! " + Thread.currentThread().getName()); } … }
Running it public static void main (String [] a){new Thread(new SimpleRun(),"Jamaica").start();new Thread(new SimpleRun(),"Fiji").start(); } 6 Jamaica7 Jamaica6 Fiji7 Fiji8 Fiji9 Fiji8 Jamaica9 JamaicaDONE! JamaicaDONE! Fiji 0 Jamaica0 Fiji1 Jamaica1 Fiji2 Jamaica3 Jamaica2 Fiji4 Jamaica3 Fiji5 Jamaica4 Fiji5 Fiji
States of a Thread sleep,suspend ,waitmethodsThe Thread is blocking on I/O Calling a sychronized method running yield()same as the schedulers action start New Thread Blocked Runnable The run method terminates.The stop method ... Dead
Class Thread • Constructors Thread(String),Thread(Runnable), Thread(Runnable, String) • Control Threads start( ), yield( ), sleep(long millis) getName( ) • Debugging Threads - toString(), countStackFrames( ), dumpStack() • Warning --- Java 1.2 has deprecatedstop( ), suspend( ), resume( ) and destroy( )
Synchronized Methods • Consider A Bank account program: class Account {int balance = 0;…void withdraw (int w) { int temp = balance; balance = temp - w;}void deposit (int d) { int temp = balance; balance = temp + d;}int balance(){ return balance;} … }
The Easy Way to get Rich • Same account referenced by two "tellers".race hazard or race condition: Balance = 100 a = getAccount("123"); b = getAccount("123"); a.withdraw(10); b.withdraw(5); temp = balance; temp = balance; balance = temp - 10; balance = temp - 5; • The value of balance could be 90,95, or 85
The Race Condition • The race condition happens because threads have their own program counter and runtime stack BUT share the process address space and "global" variables. • Eliminating this condition is called the mutual exclusion problem. • Monitors are the built-in synchronization primitives in Java.
Use Synchronized Methods • If in the code for Account, the methods “withdraw,” “deposit” and “balance” were all synchronized synchronized void withdraw(…) synchronized void deposit(…) synchronized void balance(…) • The data would be protected and work as follows:
Obtaining the lock • When a synchronized method is called, the caller has to obtain the object’s lock before the method is executed: • If the lock is not free, the calling thread waits. Thread call deposit account object t
The Lock is Free • If the lock is free the thread continues and executes the code in the method: Thread call deposit account object t
The Lock was Free... Thread • As soon as the call starts the lock is closed: • When you have obtained the lock and are executing one synchronized method, you are able to call other synchronized methods from that one, without deadlock…because you have the lock ! account object executing deposit code t
The Lock is Closed • Any other threads that call a synchronized method of the “account object” have to wait Thread account object finished executing deposit t
The Lock Become Free • When the thread that has the lock completes execution of “deposit,” the lock becomes free • When the lock opens one of the waiting threads will begin Thread account object start deposit code t
Synchronized Blocks • A “critical section” is the part of the code of a method where shared data is accessed in mutual exclusion • The “critical section” of a method may only be a small part of the code in the method • Small parts of a method may be synchronized on the object’s lock class onLineTicketing { void reserveTicket { … //fill date/price infosynchronized(this){…//reserve the seat}… //sell ticket, get moneysynchronized(this){…//confirm reservation} }
Synchronizing on other Objects • There is no limitation on which objects can be used for synchronization void aMethod {… synchronized(obj){ …//use lock of “obj” }…}
wait() and notify() • When a method executes wait(), it gives up the lock of this object, i.e. the one executing the method • In a block synchronized on “obj” the call obj.wait() gives up the lock of “obj” synchronized <type> methM {…//we have the locktry{ wait();//give up the lock //“wait()” = “this.wait()” }catch(InterruptedException e){}…
Cold Storage • The compiler makes sure you only call wait() in code that has the lock • You can only call wait() in a synchronized method or a synchronized block • If you go into the storage using wait(), you stay there until someone else calls notify() or notifyAll()for THAT lock
notify(), notifhyAll() • If several threads are waiting in the same storage, a single notify() only frees one of them • You do not know which one is freed • After being freed, the thread has to get the lock back to continue processing • If it makes sense to do that, you can call notifyAll( ) to free ALL the threads currently waiting in storage • In that case you cannot know the order in which the freed threads will run
Drawbacks of Multithreading • Complexity introduced • starvation • racing • deadlock • Waiting for shared resources could slow execution • Managing threads require additional CPU overhead