1
play

1 Transition from Blocked to Runnable Entering the Blocked state A - PowerPoint PPT Presentation

Thread states 1. New: created with the new operator (not yet started ) 2. Runnable: either running or ready to run 3. Blocked: Java threads: synchronization deactivated to wait for something 4. Dead: has executed its run


  1. Thread states 1. New: • created with the new operator (not yet started ) 2. Runnable: • either running or ready to run 3. Blocked: Java threads: synchronization • deactivated to wait for something 4. Dead: • has executed its run method to completion, or terminated by an uncaught exception a started thread is executed in its own run-time • context consisting of: program counter, call stack, and some working memory (registers, cache) 1 2 Thread states Thread states (cont.) • don't confuse the interface java.lang.Runnable with the state Runnable • "running" is not a separate state within Runnable, but Thread.currentThread () // static method identifies the current thread object (for itself) • thread.isAlive () tells if the thread has been started (is not New) and not yet Dead – you cannot directly ask whether an alive thread is Runnable or Blocked – you cannot directly ask whether a non- alive thread is still New or already Dead 3 4 1

  2. Transition from Blocked to Runnable Entering the Blocked state A blocked thread moves into the Runnable state when 1. if in sleep , the specified number of milliseconds A thread enters the blocked state when: have been expired 1. the thread goes to sleep by calling the sleep method 2. if waiting for the completion of an IO operation, the 2. the thread calls an operation that blocks until IO IO operation have finished operations are complete 3. if waiting for a lock that was owned by another 3. the thread tries to acquire a lock that is currently thread, the other thread have released its ownership held by another thread (mutual exclusion) of the lock 4. the thread waits for a condition 4. if waits for a condition, another thread signals that the condition (may) have changed – additionally, can wait for a lock or a condition with a timeout 5 6 Java Memory Model Mutual exclusion from critical code • computers can temporarily hold memory values in • basic way to protecting a shared code block: registers or local memory caches, and the compiler myLock.lock (); // a ReentrantLock object can reorder instructions to optimize throughput try { – without synchronization, threads (interleaved or parallel) may see out-of-date and/or out-of-order critical section values for the same memory locations } finally { • locks always ensure that all calculated results are myLock.unlock (); visible to other threads (flushing of caches, etc.) } • alternatively, you can declare a flag field as volatile : • only one thread at a time can enter the critical section private volatile boolean done; . . (identified and protected by this particular lock) public boolean isDone () { return done; } • any other threads calling on this lock , are blocked • a write to a volatile variable synchronizes with all until the first thread unlock s subsequent reads of that same variable (all reads • the finally clause makes sure the lock is unlocked and writes are atomic , even for long and double ) even if an exception is thrown 7 8 2

  3. Fairness Condition objects • you can specify that you want a fair locking policy: • a lock protects sections of code, allowing only one Lock fairLock = new ReentrantLock (true); thread to execute the code at a time a fair lock favors the thread that has been waiting • – a lock manages threads that are trying to enter a for the longest time protected code segment by default, locks are not required to be fair • • a lock can have one or more associated condition for implementation reasons fair locks can be – objects much slower than regular locks – each condition object manages threads that have anyway, you have no guarantee that the thread – entered a protected code section but that cannot scheduler provided by the plarform is fair proceed for some reason (usually, lack of data / • so if the thread scheduler neglects a thread, resource) it may not get the chance to be treated fairly by the lock 9 10 Condition objects (cont.) Condition objects (cont.) • some other thread must call the signalAll method to • use a condition object to manage threads that have wake up any waiting threads acquired a lock but cannot proceed with useful work change some item used in condition test . . Condition cond = lock.newCondition (); . . cond.signalAll (); // or rarely: signal () lock.lock (); try { • the condition wait must always be done in a loop while (!( ok to proceed )) // try until succeeds while (! condition ) cond.await (); cond.await (); • multiple threads may compete to acquire the lock // data available: do something useful • the first one can use up resources, and so others } finally { must then enter back to the blocked state to wait lock.unlock (); • additionally, a "spurious wakeup" (without signal) is } permitted to occur (depending on the OS) • must itself check that the condition is (still) valid 11 12 3

  4. Keyword "synchronized" Keyword synchronized (cont.) • since version 1.0, every object has an implicit lock to • the monitor lock also has a single implicit associated be used in so-called monitor methods: condition with the following operations – wait adds a thread to its set of waiting threads public synchronized void method () { body } – notifyAll unblocks all waiting threads to compete this is the equivalent of the following pseudocode: for access public void method () { // use explicit lock • these correspond to the following lock calls this.implicitLock .lock (); // pseudocode – implicitCondition .await (); // pseudocode try { – implicitCondition .signalAll (); body • the wait and notifyAll methods are final methods in } finally { Object this.implicitLock .unlock(); – so the Condition methods had to be renamed } differently: await and signalAll } 13 14 Synchronized code blocks Limitations of implicit locks and conditions • an implicit lock can be acquired also by entering a code block synchronized by an object lock: • you cannot interrupt a thread that is waiting to synchronized (obj) { // any object acquire a lock critical section // implicit lock and unlock • you cannot specify a timeout when trying to acquire a lock } • having only one single condition per lock can be • the lock is reentrant : if a thread has acquired the inefficient lock, it can acquire it again (increments a count) – cannot separate buffer empty (cannot take) vs. buffer full (cannot put) conditions • similarly, a monitor method can call other monitor methods with the same implicit lock without waiting • the virtual machine locking primitives do not map well to the most efficient locking mechanisms • you can declare a static monitor method: it uses the available in modern hardware the associated class object ("X.class") as its lock 15 16 4

  5. Lock testing and timeouts (cont.) Lock testing and timeouts • if you call tryLock with a timeout, then it can throw • can be cautious about acquiring a lock: InterruptedException when interrupted if (myLock.tryLock ()) { – can try to break up deadlocks and such // now the thread owns the lock – the lockInterruptibly method has the same try { do something } meaning as tryLock with an infinite timeout finally { myLock.unlock (); } • can also supply a timeout for a condition wait; } else { do something else } myCondition.await (10, TimeUnit.MILLISECONDS)); • can call tryLock with a timeout parameter: – returns if another thread has called signalAll - or if (myLock.tryLock(10,TimeUnit.MILLISECONDS)) if the given timeout has elapsed . . . – await methods throw an InterruptedException if – TimeUnit can be: SECONDS, MILLISECONDS, the thread is interrupted (but awaitUninterruptibly ) MICROSECONDS, or NANOSECONDS. 17 18 Summary of synchronization operations Recommendations • synchronized (lock) { . . use shared data } 1. it is best to use neither lock/condition nor the old monitor methods/code blocks ("synchronized") • synchronized void method () { . . use shared data } • in many situations, better to use mechanisms of • lock.lock () { . . } finally { lock.unlock (); } // explicit the java.util.concurrent package that do all the waiting for a condition to proceed: • locking and synchronization for you • for example, a blocking queue can synchronize try { . . threads that work on a common pipeline while (!( cannot proceed )) wait (); . . // means: this.wait (); 2. if the monitor methods work for your situation, prefer using them: } catch (InterruptedException e) { . . • less code to write and so less room for error either anyObject.wait (); or condition.await (); • 3. use explicit locks/conditions only if you need the • either anyObject.notifyAll (); or condition.signalAll (); additional power of these constructs 19 20 5

Recommend


More recommend