In the previous example of Java concurrency (a) wait () and Notifyall (), we used Wait () and notifyall () to simulate the waxing and polishing of the car. In JavaSE5, Java.util.concurrent.locks.Condition objects are also available for our use. You can use await () to suspend a task at condition. When the external condition changes, meaning that a task should continue to execute, you can either call signal () to notify the task, or call Signalall () to wake up all tasks that are suspended on this condition (as opposed to using signal (). Signalall () is a more secure way).
Here is the rewritten version of Waxonmatic.java, which contains a condition that suspends a task within waitforwaxing () or waitforbuffing ():
import java.util.concurrent.executorservice;import java.util.concurrent.executors;import java.util.concurrent.timeunit;import java.util.concurrent.locks.condition;import java.util.concurrent.locks.lock;import java.util.concurrent.locks.reentrantlock;class car { private lock lock = new reentrantlock (); private condition condition = lock.newcondition (); private boolean waxon = false;//whether waxing //waxing public void waxed () { lock.lock (); try { waxOn = true; Condition.signalall (); } finally { Lock.unlock (); } } //polished public void buffed () { lock.lock (); try { waxOn = false; condition.signalall (); } finally { lock.unlock (); } } //Wait for waxing public void waitforwaxing () throws InterruptedException { loCk.lock (); try { while (Waxon == false) { condition.await (); } } finally { lock.unlock (); } } //Waiting for polishing public void waitforbuffing () throws InterruptedException { lock.lock (); try { while (waxon == true) { condition.await (); } } finally { lock.unlock (); } }}class waxontask implements runnable { private car car; private string name; public waxontask (String name, car car) { this.name = name; this.car = car; } @Override public void run () { try { while (! Thread.interrupted ()) { system.out.println ("[" + name + "] is wax on!"); /Waxing TimeUnit.MILLISECONDS.sleep (; ) car.waxed ();//Waxing complete car.waitforbuffing ();//Waiting for polishing } } catch ( Interruptedexception e) { System.out.println ("[" + name + "] exiting waxontask via intErrupt. "); } }}class bufftask implements Runnable { private Car car; private String name; public bufftask (String name, car car) { this.name = name; this.car = car; } @Override public void run () { try { while (! Thread.interrupted ()) { car.waitforwaxing ();//wait for waxing system.out.println ("[" + name + "] buffing ... ");//Polishing timeunit.milliseconds.sleep (; ) car.buffed ();//Polishing Finish } } catch (interruptedexception e) { system.out.println ("[" + name + "] exiting bufftask via Interrupt. "); } }}public class waxomatic2 { public static void main (String[] args) throws Exception { car car = new car (); &nbsP; executorservice exec = executors.newcachedthreadpool (); //Waxing exec.execute (new Waxontask ("Waxx", car)) //polishing exec.execute (New bufftask ("Buff", car)); //run for a period of time, stop Executorservice timeunit.seconds.sleep (3 ); exec.shutdownnow (); }}
Execution Result:
[Waxx] is Wax on! [Buff] Buffing ... [Waxx] is Wax on! [Buff] Buffing ... [Waxx] is Wax on! [Buff] Buffing ... [Waxx] is Wax on! [Buff] Buffing ... [Waxx] is Wax on! [Buff] Buffing ... [Buff] Exiting Bufftask via interrupt. [Waxx] Exiting Waxontask via interrupt.
As you can see from the code, a single lock in the car's constructor produces a condition object that is used to manage communication between tasks. However, this condition object does not contain any information about the processing state, so you need to manage additional information that represents the processing state, that is, the Boolean waxon.
Note: each lock () call must be immediately followed by a try-finally clause to ensure that the lock can be released in all cases. when using the built-in version, the task must have this lock before it can invoke await (), signal (), or Signalall ().
It is also important to note that this solution is more complex than the previous one, in this case the complexity does not allow you to receive more goods. Lock and condition objects are required only in more difficult multithreaded problems.
Java Concurrency (iii) using explicit lock and condition objects