...
This noncompliant code example derives from is similar to the previous noncompliant code example for notify()
but uses the Condition
interface . The condition
field allows the threads to wait on different condition predicatesfor waiting and notification.
Code Block | ||
---|---|---|
| ||
public class ProcessStep implements Runnable { private static final Lock lock = new ReentrantLock(); private static final Condition condition = lock.newCondition(); private static int time = 0; private final int step; // Do operations when field time reaches this value public ProcessStep(int step) { this.step = step; } public void run() { lock.lock(); try { while (time != step) { condition.await(); } // Perform operations time++; condition.signal(); } catch (InterruptedException ie) { Thread.currentThread().interrupt(); // Reset interrupted status } finally { lock.unlock(); } } public static void main(String[] args) { for (int i = 4; i >= 0; i--) { new Thread(new ProcessStep(i)).start(); } } } |
...
This compliant solution uses the signalAll()
method to resume all the waiting threads. Before await()
returns the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock. The thread that is ready can perform its task, while all the threads whose condition predicates are false resume waiting.
Only the run()
method from the noncompliant code example is modified as follows:
Code Block | ||
---|---|---|
| ||
// ...
public void run() {
lock.lock();
try {
while (time != step) {
condition.await();
}
// Perform operations
time++;
condition.signalAll();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // Reset interrupted status
} finally {
lock.unlock();
}
}
|
Compliant Solution (
...
Unique Condition
...
Per Thread)
This compliant solution assigns each thread its own condition. All the Condition
objects are accessible to all the threads.
...