[jbosscache-commits] JBoss Cache SVN: r7468 - core/branches/flat/src/main/java/org/jboss/starobrno/util/concurrent.
jbosscache-commits at lists.jboss.org
jbosscache-commits at lists.jboss.org
Wed Jan 14 10:17:35 EST 2009
Author: manik.surtani at jboss.com
Date: 2009-01-14 10:17:34 -0500 (Wed, 14 Jan 2009)
New Revision: 7468
Added:
core/branches/flat/src/main/java/org/jboss/starobrno/util/concurrent/SynchronizedRestarter.java
Log:
Thread safe component restarter
Added: core/branches/flat/src/main/java/org/jboss/starobrno/util/concurrent/SynchronizedRestarter.java
===================================================================
--- core/branches/flat/src/main/java/org/jboss/starobrno/util/concurrent/SynchronizedRestarter.java (rev 0)
+++ core/branches/flat/src/main/java/org/jboss/starobrno/util/concurrent/SynchronizedRestarter.java 2009-01-14 15:17:34 UTC (rev 7468)
@@ -0,0 +1,71 @@
+package org.jboss.starobrno.util.concurrent;
+
+import org.jboss.starobrno.lifecycle.Lifecycle;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+
+/**
+ * A class that handles restarts of components via multiple threads. Specifically, if a component needs to be restarted
+ * and several threads may demand a restart but only one thread should be allowed to restart the component, then use this
+ * class.
+ * <p/>
+ * What this class guarantees is that several threads may come in while a component is being restarted, but they will
+ * block until the restart is complete.
+ * <p/>
+ * This is different from other techniques in that:
+ * <ul>
+ * <li>A simple compare-and-swap to check whether another thread is already performing a restart will result in the
+ * requesting thread returning immediately and potentially attempting to use the resource being restarted.</li>
+ * <li>A synchronized method or use of a lock would result in the thread waiting for the restart to complete, but on
+ * completion will attempt to restart the component again.</li>
+ * </ul>
+ * This implementation combines a compare-and-swap to detect a concurrent restart, as well as registering for notification
+ * for when the restart completes and then parking the thread if the CAS variable still indicates a restart in progress,
+ * and finally deregistering itself in the end.
+ *
+ * @author Manik Surtani
+ */
+public class SynchronizedRestarter
+{
+ private AtomicBoolean restartInProgress = new AtomicBoolean(false);
+ private ConcurrentHashSet<Thread> restartWaiters = new ConcurrentHashSet<Thread>();
+
+ public void restartComponent(Lifecycle component) throws Exception
+ {
+ // will only enter this block if no one else is restarting the socket
+ // and will atomically set the flag so others won't enter
+ if (restartInProgress.compareAndSet(false, true))
+ {
+ try
+ {
+ component.stop();
+ component.start();
+ }
+ finally
+ {
+ restartInProgress.set(false);
+ for (Thread waiter : restartWaiters)
+ {
+ try
+ {
+ LockSupport.unpark(waiter);
+ }
+ catch (Throwable t)
+ {
+ // do nothing; continue notifying the rest
+ }
+ }
+ }
+ }
+ else
+ {
+ // register interest in being notified after the restart
+ restartWaiters.add(Thread.currentThread());
+ // check again to ensure the restarting thread hasn't finished, then wait for that thread to finish
+ if (restartInProgress.get()) LockSupport.park();
+ // de-register interest in notification
+ restartWaiters.remove(Thread.currentThread());
+ }
+ }
+}
More information about the jbosscache-commits
mailing list