/* * 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(); } }