`

The usage of Lock and Condition

阅读更多

//: concurrency/waxomatic2/WaxOMatic2.java

// Using Lock and Condition objects.

package concurrency.waxomatic2;

 

import static java.lang.System.out;

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

{

      //car has a lock, which is used when

      //1) you are waxing the car

      //2) the wax on the care disappear

      //And obviously, these operations are exclusive to each other.

      //

      //Another very important thing about Lock object is:

      //Pay attention to the format of lock()/unlock() usage as below:

      //

      //lock.lock()

      //try

      //{

      // ... ...

      //}

      //finally

      //{

      //lock.unlock();

      //}

      private Lock lock = new ReentrantLock(); 

     

      //in java1.4 and previous, we just wait() and notify()/notifyAll() on some object, generally "this"

      //But in java1.5 concurrency, we will create a condition object, derived from Lock object.

      //And all the await() and signal()/signalAll() are on this condition object.

      private Condition condition = lock.newCondition();

 

      private boolean waxOn = false;

 

      /**

       * you are waxing the car

       */

      public void waxed()

      {

            lock.lock();

            try

            {

                  //-----location (1) where waitForWaxing() should be moved.

                  waxOn = true; // Ready to buff

                  condition.signalAll();

            }

            finally

            {

                  lock.unlock();

            }

      }

 

      /**

       * the wax on the car disappeared

       */

      public void buffed()

      {

            lock.lock();

            try

            {

                  //------location (2) where waitForBuffing() should be moved.

                  waxOn = false; // Ready for another coat of wax

                  condition.signalAll();

            }

            finally

            {

                  lock.unlock();

            }

      }

 

      /**

       * I think this method is redundant. Because the 1st step if you want to wax a car, you need to wait for waxing.

       * What I mean is, the condition.await() wrapped with while loop should be moved to location (1) of waxed() method.

       * @throws InterruptedException

       */

      public void waitForWaxing() throws InterruptedException

      {

            lock.lock();

            try

            {

                  while (waxOn == false)  //wait must be surrended by while(condition)! Don't forget this!!

                        condition.await();

            }

            finally

            {

                  lock.unlock();

            }

      }

 

      /**

       * quite similiar to the above method, should be moved to buffed() of location (2)

       * @throws InterruptedException

       */

      public void waitForBuffing() throws InterruptedException

      {

            lock.lock();

            try

            {

                  while (waxOn == true)   //wait must be surrended by while(condition)! Don't forget this!!

                        condition.await();

            }

            finally

            {

                  lock.unlock();

            }

      }

}

 

class WaxOn implements Runnable

{

      private Car car;

 

      public WaxOn(Car c)

      {

            car = c;

      }

 

      public void run()

      {

            try

            {

                  while (!Thread.interrupted())

                  {

                        out.println("Wax On! ");

                        TimeUnit.MILLISECONDS.sleep(200);

                        car.waxed();

                        car.waitForBuffing();

                  }

            }

            catch (InterruptedException e)

            {

                  out.print("Exiting via interrupt");

            }

            out.print("Ending Wax On task");

      }

}

 

class WaxOff implements Runnable

{

      private Car car;

 

      public WaxOff(Car c)

st

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics