/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.util.lock; import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Utility that uses a ReentrantReadWriteLock to control access to a service. * Threads that use the service call {@link #enterGate()} and {@link #exitGate()}, * acquiring a read lock on entrance and releasing it on exit. Thread that * controls access to the service acquires a write lock before changing the * flag that indicates whether the service is available. * *

* Here is an example of a service that uses a gate to control access * during startup and shutdown: * *

 * private Gate gate;
 * 
 * public void start() throws Exception {
 * 
 *    gate = new Gate();
 *    // Block any callers that somehow get in during the 
 *    // middle of doStartupStuff
 *    gate.blockCallers();
 *    try {
 *       doStartupStuff();
 *       gate.openGate();
 *    }
 *    catch (Exception e) {
 *       gate.closeGate();
 *    } 
 * } 
 * 
 * public void stop() throws Exception {
 * 
 *    // Block until all caller threads have exited gate
 *    gate.closeGate();
 *    // Now safe to shutdown
 *    doShutdownStuff(); 
 * } 
 * 
* * Here is an example of an interceptor that uses such a gate (how the * interceptor got a reference to the gate is unspecified): * *
 * private Gate gate;
 * 
 * public StartupShutdownInterceptor(Gate gate) {
 *    this.gate = gate;
 * }
 * 
 * public void invoke(Invocation invocation) throws Throwable {
 * 
 *    if (gate.enterGate()) {
 *    
 *       try {
 *          return invocation.invokeNext();
 *       }
 *       finally {
 *          gate.exitGate();
 *       }    
 *    }
 *    else {
 *       throw new IllegalStateException("Gate is closed");
 *    }
 * 
 * }
 * 
* * * @author Brian Stansberry */ public class Gate { private boolean open; private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); /** * Create a new Gate. */ public Gate() { } public void blockCallers() { lock.writeLock().lock(); } public void openGate() { lock.writeLock().lock(); open = true; lock.writeLock().unlock(); } public void closeGate() { lock.writeLock().lock(); open = false; lock.writeLock().unlock(); } public boolean enterGate() { lock.readLock().lock(); if (open) return true; else { lock.readLock().unlock(); return false; } } public void exitGate() { lock.readLock().unlock(); } }