Coverage report

  %line %branch
org.apache.commons.jelly.tags.threads.Mutex
71% 
83% 

 1  
 /*
 2  
  * Copyright 2002-2004 The Apache Software Foundation
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  */
 16  
 /*
 17  
   File: Mutex.java
 18  
 
 19  
   Originally written by Doug Lea and released into the public domain.
 20  
   This may be used for any purposes whatsoever without acknowledgment.
 21  
   Thanks for the assistance and support of Sun Microsystems Labs,
 22  
   and everyone contributing, testing, and using this code.
 23  
 
 24  
   History:
 25  
   Date       Who                What
 26  
   11Jun1998  dl               Create public version
 27  
 */
 28  
 
 29  
 package org.apache.commons.jelly.tags.threads;
 30  
 
 31  
 /**
 32  
  * A simple non-reentrant mutual exclusion lock.
 33  
  * The lock is free upon construction. Each acquire gets the
 34  
  * lock, and each release frees it. Releasing a lock that
 35  
  * is already free has no effect.
 36  
  * <p>
 37  
  * This implementation makes no attempt to provide any fairness
 38  
  * or ordering guarantees. If you need them, consider using one of
 39  
  * the Semaphore implementations as a locking mechanism.
 40  
  * <p>
 41  
  * <b>Sample usage</b><br>
 42  
  * <p>
 43  
  * Mutex can be useful in constructions that cannot be
 44  
  * expressed using java synchronized blocks because the
 45  
  * acquire/release pairs do not occur in the same method or
 46  
  * code block. For example, you can use them for hand-over-hand
 47  
  * locking across the nodes of a linked list. This allows
 48  
  * extremely fine-grained locking,  and so increases
 49  
  * potential concurrency, at the cost of additional complexity and
 50  
  * overhead that would normally make this worthwhile only in cases of
 51  
  * extreme contention.
 52  
  * <pre>
 53  
  * class Node {
 54  
  *   Object item;
 55  
  *   Node next;
 56  
  *   Mutex lock = new Mutex(); // each node keeps its own lock
 57  
  *
 58  
  *   Node(Object x, Node n) { item = x; next = n; }
 59  
  * }
 60  
  *
 61  
  * class List {
 62  
  *    protected Node head; // pointer to first node of list
 63  
  *
 64  
  *    // Use plain java synchronization to protect head field.
 65  
  *    //  (We could instead use a Mutex here too but there is no
 66  
  *    //  reason to do so.)
 67  
  *    protected synchronized Node getHead() { return head; }
 68  
  *
 69  
  *    boolean search(Object x) throws InterruptedException {
 70  
  *      Node p = getHead();
 71  
  *      if (p == null) return false;
 72  
  *
 73  
  *      //  (This could be made more compact, but for clarity of illustration,
 74  
  *      //  all of the cases that can arise are handled separately.)
 75  
  *
 76  
  *      p.lock.acquire();              // Prime loop by acquiring first lock.
 77  
  *                                     //    (If the acquire fails due to
 78  
  *                                     //    interrupt, the method will throw
 79  
  *                                     //    InterruptedException now,
 80  
  *                                     //    so there is no need for any
 81  
  *                                     //    further cleanup.)
 82  
  *      for (;;) {
 83  
  *        if (x.equals(p.item)) {
 84  
  *          p.lock.release();          // release current before return
 85  
  *          return true;
 86  
  *        }
 87  
  *        else {
 88  
  *          Node nextp = p.next;
 89  
  *          if (nextp == null) {
 90  
  *            p.lock.release();       // release final lock that was held
 91  
  *            return false;
 92  
  *          }
 93  
  *          else {
 94  
  *            try {
 95  
  *              nextp.lock.acquire(); // get next lock before releasing current
 96  
  *            }
 97  
  *            catch (InterruptedException ex) {
 98  
  *              p.lock.release();    // also release current if acquire fails
 99  
  *              throw ex;
 100  
  *            }
 101  
  *            p.lock.release();      // release old lock now that new one held
 102  
  *            p = nextp;
 103  
  *          }
 104  
  *        }
 105  
  *      }
 106  
  *    }
 107  
  *
 108  
  *    synchronized void add(Object x) { // simple prepend
 109  
  *      // The use of `synchronized'  here protects only head field.
 110  
  *      // The method does not need to wait out other traversers
 111  
  *      // who have already made it past head.
 112  
  *
 113  
  *      head = new Node(x, head);
 114  
  *    }
 115  
  *
 116  
  *    // ...  other similar traversal and update methods ...
 117  
  * }
 118  
  * </pre>
 119  
  * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
 120  
  *
 121  
  * --------------------------------------------------------------------------------------------
 122  
  * This Mutex is used to add the still running lock to the JellyThread tag.
 123  
  **/
 124  
 
 125  152
 public class Mutex {
 126  
 
 127  
     /** The lock status **/
 128  76
     protected boolean inuse_ = false;
 129  
 
 130  
     public void acquire() throws InterruptedException {
 131  92
         if (Thread.interrupted()) throw new InterruptedException();
 132  92
         synchronized (this) {
 133  
             try {
 134  92
                 while (inuse_) wait();
 135  90
                 inuse_ = true;
 136  90
             } catch (InterruptedException ex) {
 137  0
                 notify();
 138  0
                 throw ex;
 139  
             }
 140  90
         }
 141  90
     }
 142  
 
 143  
     public synchronized void release() {
 144  48
         inuse_ = false;
 145  48
         notify();
 146  48
     }
 147  
 
 148  
 
 149  
     public boolean attempt(long msecs) throws InterruptedException {
 150  2
         if (Thread.interrupted()) throw new InterruptedException();
 151  2
         synchronized (this) {
 152  2
             if (!inuse_) {
 153  0
                 inuse_ = true;
 154  0
                 return true;
 155  2
             } else if (msecs <= 0)
 156  0
                 return false;
 157  
             else {
 158  2
                 long waitTime = msecs;
 159  2
                 long start = System.currentTimeMillis();
 160  
                 try {
 161  2
                     for (; ;) {
 162  2
                         wait(waitTime);
 163  2
                         if (!inuse_) {
 164  0
                             inuse_ = true;
 165  0
                             return true;
 166  
                         } else {
 167  2
                             waitTime = msecs - (System.currentTimeMillis() - start);
 168  2
                             if (waitTime <= 0)
 169  2
                                 return false;
 170  
                         }
 171  
                     }
 172  
                 } catch (InterruptedException ex) {
 173  0
                     notify();
 174  0
                     throw ex;
 175  
                 }
 176  
             }
 177  0
         }
 178  
     }
 179  
 
 180  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.