24
Spring/2002 Distributed Software Engineering C:\unocourses\4350\slides\ 1 Inter-Thread communication State dependency: Guarded Methods

Inter-Thread communication State dependency: Guarded Methods

Embed Size (px)

DESCRIPTION

Inter-Thread communication State dependency: Guarded Methods. Monitors. Through synchronization one thread can safely change values that another thread will read; how does the second thread know that the values have changed? - PowerPoint PPT Presentation

Citation preview

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

1

Inter-Thread communicationState dependency: Guarded Methods

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

2

Monitors

• Through synchronization one thread can safely change values that another thread will read; how does the second thread know that the values have changed?

• Check-and-act methods are methods designed to refuse to perform actions unless they can ensure actions will succeed, in part by checking their pre-conditions

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

3

Policies on failed pre-conditions

• Balking: throw an exception indicating refusal, not failure.

• Guarded suspension: suspend action until the pre-condition becomes true

• Time-outs: place a bound on the suspension.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

4

Monitor mechanics

• Guarded methods are usually built using the following methods:– Object.wait()– Object.notify()– Object.notifyAll()

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

5

Strategies

• For each condition that needs to be waited on, write a guarded wait loop that causes the current thread to block if guard is false.

• Ensure that every method causing state changes that affect the truth value of any waited-for condition notifies threads waiting for state changes, causing them to wake up and recheck their guard conditions

• A member variable is checked by waiting thread, and modified by thread doing the modification. The checking and modification occur inside synchronized methods to avoid race conditions.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

6

• Every object has a wait set manipulated by wait, notify, notifyAll, thread.interrupt()

• Objects containing locks and wait sets are called monitors

• Any Object (read class) can serve as a monitor• Because of the relationship between wait sets and

locks, the methods wait, notify, notifyAll may be invoked only when the synchronization lock is held on their targets, a run-time error will be thrown otherwise

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

7

wait()

• A wait invocation results in the following actions:– If current thread has been interrupted, method exists

immediately throwing InterruptedException; otherwise the current thread is blocked.

– JVM places the thread in the internal and inaccessible wait set associated with the target object.

– Synchronization lock for target object is released, but all other locks held by thread are retained.

– Full release is obtained even if lock is re-entrantly held due to nested synchronized calls on target object. Upon resumption the lock status is fully restored.

– When wait pauses the thread, it atomically releases the lock on the object.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

8

notify(), notifyAll()

• An arbitrary chose thread T, if exists is removed by the JVM from the internal wait set associated with target object. No guarantee on the threat T selected.

• T must re-obtain the synchronization lock for the target object, which will always cause it to block at least until the thread calling notify releases the lock. It will continue to block if some other thread obtains lock first.

• T is resumed from the point of its wait.• NotifyAll works essentially the same as notify, except that the steps

occur, in effect simultaneously, for all threads in the wait set of the target object. However because they must acquire the lock, threads continue one at a time.

• Fundamental difference between notify() and notifyAll() is that if more than one thread is waiting notification, notify() will only signal one of waiting threads, while notifyAll() signals all waiting threads.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

9

Notify as an optimization

• Using notify is an optimization over notifyAll when– All threads are waiting for same condition– At most one thread can benefit for the condition

being met.– This is contractually true for all subclasses.

• Otherwise use notifyAll.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

10

Missed notification

• Thread B signals threadA, but threadA is not yet waiting on the notification.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

11

Early notification

• If a thread is notified wile waiting, but the condition the thread is waiting for has not been met, thread received an early notification.

• An early notification also occurs if condition is briefly met but quickly changes so is no longer met. This is due to subtle error in code: use a while for waiting not an if.

• An example: two threads are waiting for an element to be added, and only one item is added.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

12

Canceling a thread

• There are occasions to cancel a running thread (user presses cancel button)

• Cancellation is requested by interrupting the thread and writing the thread such that it watches for and responds to being interruptedThread 1 thread 2thread2.interrupt(); while(!interrupted())

doSomeWork();• An interrupt does not force the thread to halt, but it will interrupt

sleeping or waiting threads.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

13

Interrupts

• If thread.interrupt() is invoked for a thread suspended in a wait, same notify mechanism applies, except that after re-acquiring the lock, wait method throws an InterruptedException and thread’s interrupt status is set to false.

• NO telling behavior if an interrupt and a notify happen simultaneously. • isInterrupted() tests whether a thread has been interrupted.• interrupted(), a static method that tests whether the current thread

has been interrupted, and then clears the “interrupted” state of the thread. It returns true if the thread had been interrupted; false otherwise.

• Interrupted state of a thread can only be clear by that thread. There is no way for one thread to “un-interrupt” another thread.

• One of the actions of an interrupted thread is to clean up before responding to the interrupt.

• Methods sleep(), and wait() will throw InterruptedException; this exception will clear the interrupted state when thrown.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

14

Blocking and interrupt()• Any method performing a blocking operation should be designed to be

cancelled with interrupt() and should throw an appropriate exception if that occurs.

– Example: sleep(), and wait()

• In some systems, blocking I/O will respond to interruption by throwing InterruptedException

• Even if the interruption cannot be responded to during I/O, systems may check for interruption at start of operation and throw the exception

• Hence the need for an interrupted thread to clear its interrupted state if needs to perform I/O as part of its cleanup.

• You cannot assume that interrupt() will unblock a thread that is performing I/O.

• Golden rule: never hide an interrupt by clearing explicitely or by catching an InterruptedException and continuing normally.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

15

Threads and object state

• A thread dies when– The run method returns normally.– The run method completes abruptly.– The destroy method is invoked on the thread.

• When a thread dies the thread object does not go away, so you can still access its state.

• Useful when using the join() method.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

16

Time waits: wait(long msecs), wait(long msecs, int nanosecs)

• Operate as the untimed version, except that when time out occurs, it is released automatically without need for notification.

• No status indication differentiating waits that return via notifications versus a time-out.

• Counterintuitively, wait(0), and wait(0,0) are equivalent to wait()

• A timed wait may resume an arbitrarily amout of time after the requested bound due to thread contention, scheduling policies, and timer granularities.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

17

Class X {public synchronized void w() throws InterruptedException{

before(); wait(); after();}public synchronized void n(){ notifyAll();}public void before();public void after();

}

begin x.w()acquire lockbefore();

wait:release lockenter wait set

begin x.w()acquire lockbefore();

wait:release lockenter wait set

begin x.n()Wait for lockacquire locknotifyAll()release lock

Exit wait setWait for lockAcquire lock

After();Release lock

Exit wait setWait for lockAcquire lock

After();Release lock

T1

T2

T1 T2 T3 x wait set

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

18

Class X {public synchronized void w() throws InterruptedException{

before(); wait(); after();}public synchronized void n(){ notifyAll();}public void before();public void after();

}

begin x.w()acquire lockbefore();

wait:release lockenter wait set

begin x.w()acquire lockbefore();

wait:release lockenter wait set

begin x.n()Wait for lockacquire locknotifyAll()release lock

Exit wait setWait for lockAcquire lock

After();Release lock

Exit wait setWait for lockAcquire lock

After();Release lock

T1

T2

T1 T2 T3 x wait set

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

19

Cubby Hole example

• And Queue example (ch8, ch18)

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

20

join API

void join()

Waits for this thread to die.

void join(long millis)

Waits at most millis milliseconds for this thread to die.

void join(long millis, int nanos)

Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.

• In general, join is a rather crude method for thread synchronization, but is need is wanted in some instances.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

21

Ending application execution

• Your application has at least one thread (the main()) created when application is invoked. All other threads are created by the main() thread or threads created by main.

• Two kinds of threads: user and daemon.• An application terminates when all user threads

terminate. • All daemon threads are destroyed by JVM when it

detects that all user threads are finished.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

22

Thread management and security: Thread group

• Threads are organized into groups for management or security

• Thread groups form a hierarchy starting with its top group or system thread group.

• A thread group can be managed as a unit:– Interrupting all threads in a group at once.

– Placing a limit on max priority of threads in group.

– Used to define a security domain.

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

23

Threads and exception

• An uncaught exception in a thread will be handled – By the thread’s parent group if there is one.– By invoking the exception’s printStackTrace

method is there is no parent group, so that information about the exception is displayed.

– But recall, this print appears in a terminal screen. If app does not have a terminal screen the error will go unnoticed.!!!!!

Spring/2002 Distributed Software EngineeringC:\unocourses\4350\slides\DefiningThreads

24

ThreadLocal

• This class provides ThreadLocal variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal objects are typically private static variables in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

• Each thread holds an implicit reference to its copy of a ThreadLocal as long as the thread is alive and the ThreadLocal object is accessible; after a thread goes away, all of its copies of ThreadLocal variables are subject to garbage collection (unless other references to these copies exist).