You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bs...@apache.org on 2015/08/21 23:23:01 UTC
[37/51] [partial] incubator-geode git commit: GEODE-77 removing the
old jgroups subproject
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/NullSync.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/NullSync.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/NullSync.java
deleted file mode 100644
index 67ddbd7..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/NullSync.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: NullSync.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 1Aug1998 dl Create public version
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-/**
- * A No-Op implementation of Sync. Acquire never blocks,
- * Attempt always succeeds, Release has no effect.
- * However, acquire and release do detect interruption
- * and throw InterruptedException. Also, the methods
- * are synchronized, so preserve memory barrier properties
- * of Syncs.
- * <p>
- * NullSyncs can be useful in optimizing classes when
- * it is found that locking is not strictly necesssary.
- *
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
-**/
-
-
-public class NullSync implements Sync {
-
- public synchronized void acquire() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- }
-
- public synchronized boolean attempt(long msecs) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- return true;
- }
-
- public synchronized void release() {}
-
-
-}
-
-
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PooledExecutor.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PooledExecutor.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PooledExecutor.java
deleted file mode 100644
index 8341877..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PooledExecutor.java
+++ /dev/null
@@ -1,924 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: PooledExecutor.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 19Jun1998 dl Create public version
- 29aug1998 dl rely on ThreadFactoryUser,
- remove ThreadGroup-based methods
- adjusted locking policies
- 3mar1999 dl Worker threads sense decreases in pool size
- 31mar1999 dl Allow supplied channel in constructor;
- add methods createThreads, drain
- 15may1999 dl Allow infinite keepalives
- 21oct1999 dl add minimumPoolSize methods
- 7sep2000 dl BlockedExecutionHandler now an interface,
- new DiscardOldestWhenBlocked policy
- 12oct2000 dl add shutdownAfterProcessingCurrentlyQueuedTasks
- 13nov2000 dl null out task ref after run
- 08apr2001 dl declare inner class ctor protected
- 12nov2001 dl Better shutdown support
- Blocked exec handlers can throw IE
- Simplify locking scheme
- 25jan2001 dl {get,set}BlockedExecutionHandler now public
- 17may2002 dl null out task var in worker run to enable GC.
- 30aug2003 dl check for new tasks when timing out
- 18feb2004 dl replace dead thread if no others left
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-import java.util.*;
-
-/**
- * A tunable, extensible thread pool class. The main supported public
- * method is <code>execute(Runnable command)</code>, which can be
- * called instead of directly creating threads to execute commands.
- *
- * <p>
- * Thread pools can be useful for several, usually intertwined
- * reasons:
- *
- * <ul>
- *
- * <li> To bound resource use. A limit can be placed on the maximum
- * number of simultaneously executing threads.
- *
- * <li> To manage concurrency levels. A targeted number of threads
- * can be allowed to execute simultaneously.
- *
- * <li> To manage a set of threads performing related tasks.
- *
- * <li> To minimize overhead, by reusing previously constructed
- * Thread objects rather than creating new ones. (Note however
- * that pools are hardly ever cure-alls for performance problems
- * associated with thread construction, especially on JVMs that
- * themselves internally pool or recycle threads.)
- *
- * </ul>
- *
- * These goals introduce a number of policy parameters that are
- * encapsulated in this class. All of these parameters have defaults
- * and are tunable, either via get/set methods, or, in cases where
- * decisions should hold across lifetimes, via methods that can be
- * easily overridden in subclasses. The main, most commonly set
- * parameters can be established in constructors. Policy choices
- * across these dimensions can and do interact. Be careful, and
- * please read this documentation completely before using! See also
- * the usage examples below.
- *
- * <dl>
- * <dt> Queueing
- *
- * <dd> By default, this pool uses queueless synchronous channels to
- * to hand off work to threads. This is a safe, conservative policy
- * that avoids lockups when handling sets of requests that might
- * have internal dependencies. (In these cases, queuing one task
- * could lock up another that would be able to continue if the
- * queued task were to run.) If you are sure that this cannot
- * happen, then you can instead supply a queue of some sort (for
- * example, a BoundedBuffer or LinkedQueue) in the constructor.
- * This will cause new commands to be queued in cases where all
- * MaximumPoolSize threads are busy. Queues are sometimes
- * appropriate when each task is completely independent of others,
- * so tasks cannot affect each others execution. For example, in an
- * http server. <p>
- *
- * When given a choice, this pool always prefers adding a new thread
- * rather than queueing if there are currently fewer than the
- * current getMinimumPoolSize threads running, but otherwise always
- * prefers queuing a request rather than adding a new thread. Thus,
- * if you use an unbounded buffer, you will never have more than
- * getMinimumPoolSize threads running. (Since the default
- * minimumPoolSize is one, you will probably want to explicitly
- * setMinimumPoolSize.) <p>
- *
- * While queuing can be useful in smoothing out transient bursts of
- * requests, especially in socket-based services, it is not very
- * well behaved when commands continue to arrive on average faster
- * than they can be processed. Using bounds for both the queue and
- * the pool size, along with run-when-blocked policy is often a
- * reasonable response to such possibilities. <p>
- *
- * Queue sizes and maximum pool sizes can often be traded off for
- * each other. Using large queues and small pools minimizes CPU
- * usage, OS resources, and context-switching overhead, but can lead
- * to artifically low throughput. Especially if tasks frequently
- * block (for example if they are I/O bound), a JVM and underlying
- * OS may be able to schedule time for more threads than you
- * otherwise allow. Use of small queues or queueless handoffs
- * generally requires larger pool sizes, which keeps CPUs busier but
- * may encounter unacceptable scheduling overhead, which also
- * decreases throughput. <p>
- *
- * <dt> Maximum Pool size
- *
- * <dd> The maximum number of threads to use, when needed. The pool
- * does not by default preallocate threads. Instead, a thread is
- * created, if necessary and if there are fewer than the maximum,
- * only when an <code>execute</code> request arrives. The default
- * value is (for all practical purposes) infinite --
- * <code>Integer.MAX_VALUE</code>, so should be set in the
- * constructor or the set method unless you are just using the pool
- * to minimize construction overhead. Because task handoffs to idle
- * worker threads require synchronization that in turn relies on JVM
- * scheduling policies to ensure progress, it is possible that a new
- * thread will be created even though an existing worker thread has
- * just become idle but has not progressed to the point at which it
- * can accept a new task. This phenomenon tends to occur on some
- * JVMs when bursts of short tasks are executed. <p>
- *
- * <dt> Minimum Pool size
- *
- * <dd> The minimum number of threads to use, when needed (default
- * 1). When a new request is received, and fewer than the minimum
- * number of threads are running, a new thread is always created to
- * handle the request even if other worker threads are idly waiting
- * for work. Otherwise, a new thread is created only if there are
- * fewer than the maximum and the request cannot immediately be
- * queued. <p>
- *
- * <dt> Preallocation
- *
- * <dd> You can override lazy thread construction policies via
- * method createThreads, which establishes a given number of warm
- * threads. Be aware that these preallocated threads will time out
- * and die (and later be replaced with others if needed) if not used
- * within the keep-alive time window. If you use preallocation, you
- * probably want to increase the keepalive time. The difference
- * between setMinimumPoolSize and createThreads is that
- * createThreads immediately establishes threads, while setting the
- * minimum pool size waits until requests arrive. <p>
- *
- * <dt> Keep-alive time
- *
- * <dd> If the pool maintained references to a fixed set of threads
- * in the pool, then it would impede garbage collection of otherwise
- * idle threads. This would defeat the resource-management aspects
- * of pools. One solution would be to use weak references. However,
- * this would impose costly and difficult synchronization issues.
- * Instead, threads are simply allowed to terminate and thus be
- * GCable if they have been idle for the given keep-alive time. The
- * value of this parameter represents a trade-off between GCability
- * and construction time. In most current Java VMs, thread
- * construction and cleanup overhead is on the order of
- * milliseconds. The default keep-alive value is one minute, which
- * means that the time needed to construct and then GC a thread is
- * expended at most once per minute.
- * <p>
- *
- * To establish worker threads permanently, use a <em>negative</em>
- * argument to setKeepAliveTime. <p>
- *
- * <dt> Blocked execution policy
- *
- * <dd> If the maximum pool size or queue size is bounded, then it
- * is possible for incoming <code>execute</code> requests to
- * block. There are four supported policies for handling this
- * problem, and mechanics (based on the Strategy Object pattern) to
- * allow others in subclasses: <p>
- *
- * <dl>
- * <dt> Run (the default)
- * <dd> The thread making the <code>execute</code> request
- * runs the task itself. This policy helps guard against lockup.
- * <dt> Wait
- * <dd> Wait until a thread becomes available. This
- * policy should, in general, not be used if the minimum number of
- * of threads is zero, in which case a thread may never become
- * available.
- * <dt> Abort
- * <dd> Throw a RuntimeException
- * <dt> Discard
- * <dd> Throw away the current request and return.
- * <dt> DiscardOldest
- * <dd> Throw away the oldest request and return.
- * </dl>
- *
- * Other plausible policies include raising the maximum pool size
- * after checking with some other objects that this is OK. <p>
- *
- * These cases can never occur if the maximum pool size is unbounded
- * or the queue is unbounded. In these cases you instead face
- * potential resource exhaustion.) The execute method does not
- * throw any checked exceptions in any of these cases since any
- * errors associated with them must normally be dealt with via
- * handlers or callbacks. (Although in some cases, these might be
- * associated with throwing unchecked exceptions.) You may wish to
- * add special implementations even if you choose one of the listed
- * policies. For example, the supplied Discard policy does not
- * inform the caller of the drop. You could add your own version
- * that does so. Since choice of policies is normally a system-wide
- * decision, selecting a policy affects all calls to
- * <code>execute</code>. If for some reason you would instead like
- * to make per-call decisions, you could add variant versions of the
- * <code>execute</code> method (for example,
- * <code>executeIfWouldNotBlock</code>) in subclasses. <p>
- *
- * <dt> Thread construction parameters
- *
- * <dd> A settable ThreadFactory establishes each new thread. By
- * default, it merely generates a new instance of class Thread, but
- * can be changed to use a Thread subclass, to set priorities,
- * ThreadLocals, etc. <p>
- *
- * <dt> Interruption policy
- *
- * <dd> Worker threads check for interruption after processing each
- * command, and terminate upon interruption. Fresh threads will
- * replace them if needed. Thus, new tasks will not start out in an
- * interrupted state due to an uncleared interruption in a previous
- * task. Also, unprocessed commands are never dropped upon
- * interruption. It would conceptually suffice simply to clear
- * interruption between tasks, but implementation characteristics of
- * interruption-based methods are uncertain enough to warrant this
- * conservative strategy. It is a good idea to be equally
- * conservative in your code for the tasks running within pools.
- * <p>
- *
- * <dt> Shutdown policy
- *
- * <dd> The interruptAll method interrupts, but does not disable the
- * pool. Two different shutdown methods are supported for use when
- * you do want to (permanently) stop processing tasks. Method
- * shutdownAfterProcessingCurrentlyQueuedTasks waits until all
- * current tasks are finished. The shutDownNow method interrupts
- * current threads and leaves other queued requests unprocessed.
- * <p>
- *
- * <dt> Handling requests after shutdown
- *
- * <dd> When the pool is shutdown, new incoming requests are handled
- * by the blockedExecutionHandler. By default, the handler is set to
- * discard new requests, but this can be set with an optional
- * argument to method
- * shutdownAfterProcessingCurrentlyQueuedTasks. <p> Also, if you are
- * using some form of queuing, you may wish to call method drain()
- * to remove (and return) unprocessed commands from the queue after
- * shutting down the pool and its clients. If you need to be sure
- * these commands are processed, you can then run() each of the
- * commands in the list returned by drain().
- *
- * </dl>
- * <p>
- *
- * <b>Usage examples.</b>
- * <p>
- *
- * Probably the most common use of pools is in statics or singletons
- * accessible from a number of classes in a package; for example:
- *
- * <pre>
- * class MyPool {
- * // initialize to use a maximum of 8 threads.
- * static PooledExecutor pool = new PooledExecutor(8);
- * }
- * </pre>
- * Here are some sample variants in initialization:
- * <ol>
- * <li> Using a bounded buffer of 10 tasks, at least 4 threads (started only
- * when needed due to incoming requests), but allowing
- * up to 100 threads if the buffer gets full.
- * <pre>
- * pool = new PooledExecutor(new BoundedBuffer(10), 100);
- * pool.setMinimumPoolSize(4);
- * </pre>
- * <li> Same as (1), except pre-start 9 threads, allowing them to
- * die if they are not used for five minutes.
- * <pre>
- * pool = new PooledExecutor(new BoundedBuffer(10), 100);
- * pool.setMinimumPoolSize(4);
- * pool.setKeepAliveTime(1000 * 60 * 5);
- * pool.createThreads(9);
- * </pre>
- * <li> Same as (2) except clients abort if both the buffer is full and
- * all 100 threads are busy:
- * <pre>
- * pool = new PooledExecutor(new BoundedBuffer(10), 100);
- * pool.setMinimumPoolSize(4);
- * pool.setKeepAliveTime(1000 * 60 * 5);
- * pool.abortWhenBlocked();
- * pool.createThreads(9);
- * </pre>
- * <li> An unbounded queue serviced by exactly 5 threads:
- * <pre>
- * pool = new PooledExecutor(new LinkedQueue());
- * pool.setKeepAliveTime(-1); // live forever
- * pool.createThreads(5);
- * </pre>
- * </ol>
- *
- * <p>
- * <b>Usage notes.</b>
- * <p>
- *
- * Pools do not mesh well with using thread-specific storage via
- * java.lang.ThreadLocal. ThreadLocal relies on the identity of a
- * thread executing a particular task. Pools use the same thread to
- * perform different tasks. <p>
- *
- * If you need a policy not handled by the parameters in this class
- * consider writing a subclass. <p>
- *
- * Version note: Previous versions of this class relied on
- * ThreadGroups for aggregate control. This has been removed, and the
- * method interruptAll added, to avoid differences in behavior across
- * JVMs.
- *
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- **/
-
-public class PooledExecutor extends ThreadFactoryUser implements Executor {
-
- /**
- * The maximum pool size; used if not otherwise specified. Default
- * value is essentially infinite (Integer.MAX_VALUE)
- **/
- public static final int DEFAULT_MAXIMUMPOOLSIZE = Integer.MAX_VALUE;
-
- /**
- * The minimum pool size; used if not otherwise specified. Default
- * value is 1.
- **/
- public static final int DEFAULT_MINIMUMPOOLSIZE = 1;
-
- /**
- * The maximum time to keep worker threads alive waiting for new
- * tasks; used if not otherwise specified. Default value is one
- * minute (60000 milliseconds).
- **/
- public static final long DEFAULT_KEEPALIVETIME = 60 * 1000;
-
- /** The maximum number of threads allowed in pool. **/
- protected int maximumPoolSize_ = DEFAULT_MAXIMUMPOOLSIZE;
-
- /** The minumum number of threads to maintain in pool. **/
- protected int minimumPoolSize_ = DEFAULT_MINIMUMPOOLSIZE;
-
- /** Current pool size. **/
- protected int poolSize_ = 0;
-
- /** The maximum time for an idle thread to wait for new task. **/
- protected long keepAliveTime_ = DEFAULT_KEEPALIVETIME;
-
- /**
- * Shutdown flag - latches true when a shutdown method is called
- * in order to disable queuing/handoffs of new tasks.
- **/
- protected boolean shutdown_ = false;
-
- /**
- * The channel used to hand off the command to a thread in the pool.
- **/
- protected final Channel handOff_;
-
- /**
- * The set of active threads, declared as a map from workers to
- * their threads. This is needed by the interruptAll method. It
- * may also be useful in subclasses that need to perform other
- * thread management chores.
- **/
- protected final Map threads_;
-
- /** The current handler for unserviceable requests. **/
- protected BlockedExecutionHandler blockedExecutionHandler_;
-
- /**
- * Create a new pool with all default settings
- **/
-
- public PooledExecutor() {
- this (new SynchronousChannel(), DEFAULT_MAXIMUMPOOLSIZE);
- }
-
- /**
- * Create a new pool with all default settings except
- * for maximum pool size.
- **/
-
- public PooledExecutor(int maxPoolSize) {
- this(new SynchronousChannel(), maxPoolSize);
- }
-
- /**
- * Create a new pool that uses the supplied Channel for queuing, and
- * with all default parameter settings.
- **/
-
- public PooledExecutor(Channel channel) {
- this(channel, DEFAULT_MAXIMUMPOOLSIZE);
- }
-
- /**
- * Create a new pool that uses the supplied Channel for queuing, and
- * with all default parameter settings except for maximum pool size.
- **/
-
- public PooledExecutor(Channel channel, int maxPoolSize) {
- maximumPoolSize_ = maxPoolSize;
- handOff_ = channel;
- runWhenBlocked();
- threads_ = new HashMap();
- }
-
- /**
- * Return the maximum number of threads to simultaneously execute
- * New unqueued requests will be handled according to the current
- * blocking policy once this limit is exceeded.
- **/
- public synchronized int getMaximumPoolSize() {
- return maximumPoolSize_;
- }
-
- /**
- * Set the maximum number of threads to use. Decreasing the pool
- * size will not immediately kill existing threads, but they may
- * later die when idle.
- * @exception IllegalArgumentException if less or equal to zero.
- * (It is
- * not considered an error to set the maximum to be less than than
- * the minimum. However, in this case there are no guarantees
- * about behavior.)
- **/
- public synchronized void setMaximumPoolSize(int newMaximum) {
- if (newMaximum <= 0) throw new IllegalArgumentException();
- maximumPoolSize_ = newMaximum;
- }
-
- /**
- * Return the minimum number of threads to simultaneously execute.
- * (Default value is 1). If fewer than the mininum number are
- * running upon reception of a new request, a new thread is started
- * to handle this request.
- **/
- public synchronized int getMinimumPoolSize() {
- return minimumPoolSize_;
- }
-
- /**
- * Set the minimum number of threads to use.
- * @exception IllegalArgumentException if less than zero. (It is not
- * considered an error to set the minimum to be greater than the
- * maximum. However, in this case there are no guarantees about
- * behavior.)
- **/
- public synchronized void setMinimumPoolSize(int newMinimum) {
- if (newMinimum < 0) throw new IllegalArgumentException();
- minimumPoolSize_ = newMinimum;
- }
-
- /**
- * Return the current number of active threads in the pool. This
- * number is just a snaphot, and may change immediately upon
- * returning
- **/
- public synchronized int getPoolSize() {
- return poolSize_;
- }
-
- /**
- * Return the number of milliseconds to keep threads alive waiting
- * for new commands. A negative value means to wait forever. A zero
- * value means not to wait at all.
- **/
- public synchronized long getKeepAliveTime() {
- return keepAliveTime_;
- }
-
- /**
- * Set the number of milliseconds to keep threads alive waiting for
- * new commands. A negative value means to wait forever. A zero
- * value means not to wait at all.
- **/
- public synchronized void setKeepAliveTime(long msecs) {
- keepAliveTime_ = msecs;
- }
-
- /** Get the handler for blocked execution **/
- public synchronized BlockedExecutionHandler getBlockedExecutionHandler() {
- return blockedExecutionHandler_;
- }
-
- /** Set the handler for blocked execution **/
- public synchronized void setBlockedExecutionHandler(BlockedExecutionHandler h) {
- blockedExecutionHandler_ = h;
- }
-
- /**
- * Create and start a thread to handle a new command. Call only
- * when holding lock.
- **/
- protected void addThread(Runnable command) {
- Worker worker = new Worker(command);
- Thread thread = getThreadFactory().newThread(worker);
- threads_.put(worker, thread);
- ++poolSize_;
- thread.start();
- }
-
- /**
- * Create and start up to numberOfThreads threads in the pool.
- * Return the number created. This may be less than the number
- * requested if creating more would exceed maximum pool size bound.
- **/
- public int createThreads(int numberOfThreads) {
- int ncreated = 0;
- for (int i = 0; i < numberOfThreads; ++i) {
- synchronized(this) {
- if (poolSize_ < maximumPoolSize_) {
- addThread(null);
- ++ncreated;
- }
- else
- break;
- }
- }
- return ncreated;
- }
-
- /**
- * Interrupt all threads in the pool, causing them all to
- * terminate. Assuming that executed tasks do not disable (clear)
- * interruptions, each thread will terminate after processing its
- * current task. Threads will terminate sooner if the executed tasks
- * themselves respond to interrupts.
- **/
- public synchronized void interruptAll() {
- for (Iterator it = threads_.values().iterator(); it.hasNext(); ) {
- Thread t = (Thread)(it.next());
- t.interrupt();
- }
- }
-
- /**
- * Interrupt all threads and disable construction of new
- * threads. Any tasks entered after this point will be discarded. A
- * shut down pool cannot be restarted.
- */
- public void shutdownNow() {
- shutdownNow(new DiscardWhenBlocked());
- }
-
- /**
- * Interrupt all threads and disable construction of new
- * threads. Any tasks entered after this point will be handled by
- * the given BlockedExecutionHandler. A shut down pool cannot be
- * restarted.
- */
- public synchronized void shutdownNow(BlockedExecutionHandler handler) {
- setBlockedExecutionHandler(handler);
- shutdown_ = true; // don't allow new tasks
- minimumPoolSize_ = maximumPoolSize_ = 0; // don't make new threads
- interruptAll(); // interrupt all existing threads
- }
-
- /**
- * Terminate threads after processing all elements currently in
- * queue. Any tasks entered after this point will be discarded. A
- * shut down pool cannot be restarted.
- **/
- public void shutdownAfterProcessingCurrentlyQueuedTasks() {
- shutdownAfterProcessingCurrentlyQueuedTasks(new DiscardWhenBlocked());
- }
-
- /**
- * Terminate threads after processing all elements currently in
- * queue. Any tasks entered after this point will be handled by the
- * given BlockedExecutionHandler. A shut down pool cannot be
- * restarted.
- **/
- public synchronized void shutdownAfterProcessingCurrentlyQueuedTasks(BlockedExecutionHandler handler) {
- setBlockedExecutionHandler(handler);
- shutdown_ = true;
- if (poolSize_ == 0) // disable new thread construction when idle
- minimumPoolSize_ = maximumPoolSize_ = 0;
- }
-
- /**
- * Return true if a shutDown method has succeeded in terminating all
- * threads.
- */
- public synchronized boolean isTerminatedAfterShutdown() {
- return shutdown_ && poolSize_ == 0;
- }
-
- /**
- * Wait for a shutdown pool to fully terminate, or until the timeout
- * has expired. This method may only be called <em>after</em>
- * invoking shutdownNow or
- * shutdownAfterProcessingCurrentlyQueuedTasks.
- *
- * @param maxWaitTime the maximum time in milliseconds to wait
- * @return true if the pool has terminated within the max wait period
- * @exception IllegalStateException if shutdown has not been requested
- * @exception InterruptedException if the current thread has been interrupted in the course of waiting
- */
- public synchronized boolean awaitTerminationAfterShutdown(long maxWaitTime) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- if (!shutdown_)
- throw new IllegalStateException();
- if (poolSize_ == 0)
- return true;
- long waitTime = maxWaitTime;
- if (waitTime <= 0)
- return false;
- long start = System.currentTimeMillis();
- for (;;) {
- wait(waitTime);
- if (poolSize_ == 0)
- return true;
- waitTime = maxWaitTime - (System.currentTimeMillis() - start);
- if (waitTime <= 0)
- return false;
- }
- }
-
- /**
- * Wait for a shutdown pool to fully terminate. This method may
- * only be called <em>after</em> invoking shutdownNow or
- * shutdownAfterProcessingCurrentlyQueuedTasks.
- *
- * @exception IllegalStateException if shutdown has not been requested
- * @exception InterruptedException if the current thread has been interrupted in the course of waiting
- */
- public synchronized void awaitTerminationAfterShutdown() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition in case poolSize_ is 0
- if (!shutdown_)
- throw new IllegalStateException();
- while (poolSize_ > 0)
- wait();
- }
-
- /**
- * Remove all unprocessed tasks from pool queue, and return them in
- * a java.util.List. Thsi method should be used only when there are
- * not any active clients of the pool. Otherwise you face the
- * possibility that the method will loop pulling out tasks as
- * clients are putting them in. This method can be useful after
- * shutting down a pool (via shutdownNow) to determine whether there
- * are any pending tasks that were not processed. You can then, for
- * example execute all unprocessed commands via code along the lines
- * of:
- *
- * <pre>
- * List tasks = pool.drain();
- * for (Iterator it = tasks.iterator(); it.hasNext();)
- * ( (Runnable)(it.next()) ).run();
- * </pre>
- **/
- public List drain() {
-// boolean wasInterrupted = false; GemStoneAddition
- Vector tasks = new Vector();
- for (;;) {
- boolean interrupted = Thread.interrupted(); // GemStoneAddition
- try {
- Object x = handOff_.poll(0);
- if (x == null)
- break;
- else
- tasks.addElement(x);
- }
- catch (InterruptedException ex) {
-// wasInterrupted = true; // postpone re-interrupt until drained
- interrupted = true;
- }
- finally { // GemStoneAddition
- if (interrupted) {
- Thread.currentThread().interrupt();
- }
- }
- }
-// if (wasInterrupted) Thread.currentThread().interrupt();
- return tasks;
- }
-
- /**
- * Cleanup method called upon termination of worker thread.
- **/
- protected synchronized void workerDone(Worker w) {
- threads_.remove(w);
- if (--poolSize_ == 0 && shutdown_) {
- maximumPoolSize_ = minimumPoolSize_ = 0; // disable new threads
- notifyAll(); // notify awaitTerminationAfterShutdown
- }
-
- // Create a replacement if needed
- if (poolSize_ == 0 || poolSize_ < minimumPoolSize_) {
- try {
- Runnable r = (Runnable)(handOff_.poll(0));
- if (r != null && !shutdown_) // just consume task if shut down
- addThread(r);
- } catch(InterruptedException ie) {
- return;
- }
- }
- }
-
- /**
- * Get a task from the handoff queue, or null if shutting down.
- **/
- protected Runnable getTask() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- long waitTime;
- synchronized(this) {
- if (poolSize_ > maximumPoolSize_) // Cause to die if too many threads
- return null;
- waitTime = (shutdown_)? 0 : keepAliveTime_;
- }
- if (waitTime >= 0)
- return (Runnable)(handOff_.poll(waitTime));
- else
- return (Runnable)(handOff_.take());
- }
-
-
- /**
- * Class defining the basic run loop for pooled threads.
- **/
- protected class Worker implements Runnable {
- protected Runnable firstTask_;
-
- protected Worker(Runnable firstTask) { firstTask_ = firstTask; }
-
- public void run() {
- try {
- Runnable task = firstTask_;
- firstTask_ = null; // enable GC
-
- if (task != null) {
- task.run();
- task = null;
- }
-
- while ( (task = getTask()) != null) {
- task.run();
- task = null;
- }
- }
- catch (InterruptedException ex) {
- Thread.currentThread().interrupt(); // GemStoneAddition
- // fall through
- }
- finally {
- workerDone(this);
- }
- }
- }
-
- /**
- * Class for actions to take when execute() blocks. Uses Strategy
- * pattern to represent different actions. You can add more in
- * subclasses, and/or create subclasses of these. If so, you will
- * also want to add or modify the corresponding methods that set the
- * current blockedExectionHandler_.
- **/
- public interface BlockedExecutionHandler {
- /**
- * Return true if successfully handled so, execute should
- * terminate; else return false if execute loop should be retried.
- **/
- boolean blockedAction(Runnable command) throws InterruptedException;
- }
-
- /** Class defining Run action. **/
- static/*GemStoneAddition*/ protected class RunWhenBlocked implements BlockedExecutionHandler {
- public boolean blockedAction(Runnable command) {
- command.run();
- return true;
- }
- }
-
- /**
- * Set the policy for blocked execution to be that the current
- * thread executes the command if there are no available threads in
- * the pool.
- **/
- public void runWhenBlocked() {
- setBlockedExecutionHandler(new RunWhenBlocked());
- }
-
- /** Class defining Wait action. **/
- protected class WaitWhenBlocked implements BlockedExecutionHandler {
- public boolean blockedAction(Runnable command) throws InterruptedException{
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- synchronized(PooledExecutor.this) {
- if (shutdown_)
- return true;
- }
- handOff_.put(command);
- return true;
- }
- }
-
- /**
- * Set the policy for blocked execution to be to wait until a thread
- * is available, unless the pool has been shut down, in which case
- * the action is discarded.
- **/
- public void waitWhenBlocked() {
- setBlockedExecutionHandler(new WaitWhenBlocked());
- }
-
- /** Class defining Discard action. **/
- static/*GemStoneAddition*/ protected class DiscardWhenBlocked implements BlockedExecutionHandler {
- public boolean blockedAction(Runnable command) {
- return true;
- }
- }
-
- /**
- * Set the policy for blocked execution to be to return without
- * executing the request.
- **/
- public void discardWhenBlocked() {
- setBlockedExecutionHandler(new DiscardWhenBlocked());
- }
-
-
- /** Class defining Abort action. **/
- static/*GemStoneAddition*/ protected class AbortWhenBlocked implements BlockedExecutionHandler {
- public boolean blockedAction(Runnable command) {
- throw new RuntimeException("Pool is blocked");
- }
- }
-
- /**
- * Set the policy for blocked execution to be to
- * throw a RuntimeException.
- **/
- public void abortWhenBlocked() {
- setBlockedExecutionHandler(new AbortWhenBlocked());
- }
-
-
- /**
- * Class defining DiscardOldest action. Under this policy, at most
- * one old unhandled task is discarded. If the new task can then be
- * handed off, it is. Otherwise, the new task is run in the current
- * thread (i.e., RunWhenBlocked is used as a backup policy.)
- **/
- protected class DiscardOldestWhenBlocked implements BlockedExecutionHandler {
- public boolean blockedAction(Runnable command) throws InterruptedException{
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition for safety
- handOff_.poll(0);
- if (!handOff_.offer(command, 0))
- command.run();
- return true;
- }
- }
-
- /**
- * Set the policy for blocked execution to be to discard the oldest
- * unhandled request
- **/
- public void discardOldestWhenBlocked() {
- setBlockedExecutionHandler(new DiscardOldestWhenBlocked());
- }
-
- /**
- * Arrange for the given command to be executed by a thread in this
- * pool. The method normally returns when the command has been
- * handed off for (possibly later) execution.
- **/
- public void execute(Runnable command) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- for (;;) {
- synchronized(this) {
- if (!shutdown_) {
- int size = poolSize_;
-
- // Ensure minimum number of threads
- if (size < minimumPoolSize_) {
- addThread(command);
- return;
- }
-
- // Try to give to existing thread
- if (handOff_.offer(command, 0)) {
- return;
- }
-
- // If cannot handoff and still under maximum, create new thread
- if (size < maximumPoolSize_) {
- addThread(command);
- return;
- }
- }
- }
-
- // Cannot hand off and cannot create -- ask for help
- if (getBlockedExecutionHandler().blockedAction(command)) {
- return;
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PrioritySemaphore.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PrioritySemaphore.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PrioritySemaphore.java
deleted file mode 100644
index 61d79d3..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PrioritySemaphore.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: PrioritySemaphore.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
-*/
-
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-/**
- * A Semaphore that grants requests to threads with higher
- * Thread priority rather than lower priority when there is
- * contention. Ordering of requests with the same priority
- * is approximately FIFO.
- * Priorities are based on Thread.getPriority.
- * Changing the priority of an already-waiting thread does NOT
- * change its ordering. This class also does not specially deal with priority
- * inversion -- when a new high-priority thread enters
- * while a low-priority thread is currently running, their
- * priorities are <em>not</em> artificially manipulated.
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
-
-**/
-
-public class PrioritySemaphore extends QueuedSemaphore {
-
- /**
- * Create a Semaphore with the given initial number of permits.
- * Using a seed of one makes the semaphore act as a mutual exclusion lock.
- * Negative seeds are also allowed, in which case no acquires will proceed
- * until the number of releases has pushed the number of permits past 0.
- **/
-
-
- public PrioritySemaphore(long initialPermits) {
- super(new PriorityWaitQueue(), initialPermits);
- }
-
- protected static class PriorityWaitQueue extends WaitQueue {
-
-
- /** An array of wait queues, one per priority **/
- protected final FIFOSemaphore.FIFOWaitQueue[] cells_ =
- new FIFOSemaphore.FIFOWaitQueue[Thread.MAX_PRIORITY -
- Thread.MIN_PRIORITY + 1];
-
- /**
- * The index of the highest priority cell that may need to be signalled,
- * or -1 if none. Used to minimize array traversal.
- **/
-
- protected int maxIndex_ = -1;
-
- protected PriorityWaitQueue() {
- for (int i = 0; i < cells_.length; ++i)
- cells_[i] = new FIFOSemaphore.FIFOWaitQueue();
- }
-
- @Override // GemStoneAddition
- protected void insert(WaitNode w) {
- int idx = Thread.currentThread().getPriority() - Thread.MIN_PRIORITY;
- cells_[idx].insert(w);
- if (idx > maxIndex_) maxIndex_ = idx;
- }
-
- @Override // GemStoneAddition
- protected WaitNode extract() {
- for (;;) {
- int idx = maxIndex_;
- if (idx < 0)
- return null;
- WaitNode w = cells_[idx].extract();
- if (w != null)
- return w;
- else
- --maxIndex_;
- }
- }
- }
-
-
-
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PropertyChangeMulticaster.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PropertyChangeMulticaster.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PropertyChangeMulticaster.java
deleted file mode 100644
index f6db505..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/PropertyChangeMulticaster.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: PropertyChangeMulticaster.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- This class is based on Sun JDK java.beans.VetoableChangeSupport,
- which is copyrighted by Sun. (It shares practically no code, but for
- consistency, the documentation was lifted and adapted here.)
-
- History:
- Date Who What
- 14Mar1999 dl first release
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeEvent;
-import java.util.HashMap;
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
-import java.io.IOException;
-
-/**
- * This class is interoperable with java.beans.PropertyChangeSupport,
- * but relies on a streamlined copy-on-write scheme similar to
- * that used in CopyOnWriteArrayList. This leads to much better
- * performance in most event-intensive programs. It also adheres to clarified
- * semantics of add and remove operations.
- * <p>
- * <b>Sample usage.</b>
- *
- * <pre>
- * class Thing {
- * protected Color myColor = Color.red; // an example property
- *
- * protected PropertyChangeMulticaster listeners =
- * new PropertyChangeMulticaster(this);
- *
- * // registration methods, including:
- * void addListener(PropertyChangeListener l) {
- * // Use the `ifAbsent' version to avoid duplicate notifications
- * listeners.addPropertyChangeListenerIfAbsent(l);
- * }
- *
- * public synchronized Color getColor() { // accessor
- * return myColor;
- * }
- *
- * // internal synchronized state change method; returns old value
- * protected synchronized Color assignColor(Color newColor) {
- * Color oldColor = myColor;
- * myColor = newColor;
- * return oldColor;
- * }
- *
- * public void setColor(Color newColor) {
- * // atomically change state
- * Color oldColor = assignColor(newColor);
- * // broadcast change notification without holding synch lock
- * listeners.firePropertyChange("color", oldColor, newColor);
- * }
- * }
- * </pre>
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- **/
-
-public class PropertyChangeMulticaster implements Serializable {
- private static final long serialVersionUID = 3115925028370351924L;
-
- // In order to allow this class to be lifted out without using
- // the whole package, the basic mechanics of CopyOnWriteArrayList
- // are used here, but not the class itself.
- // This also makes it barely faster.
-
- /**
- * The array of listeners. Copied on each update
- **/
-
- protected transient PropertyChangeListener[] listeners = new PropertyChangeListener[0];
-
-
- /**
- * The object to be provided as the "source" for any generated events.
- * @serial
- */
- protected final Object source;
-
- /**
- * HashMap for managing listeners for specific properties.
- * Maps property names to PropertyChangeMulticaster objects.
- * @serial
- */
- protected HashMap children;
-
- /**
- * Return the child associated with property, or null if no such
- **/
-
- protected synchronized PropertyChangeMulticaster getChild(String propertyName) {
- return (children == null)? null :
- ((PropertyChangeMulticaster)children.get(propertyName));
- }
-
-
- /**
- * Constructs a <code>PropertyChangeMulticaster</code> object.
- *
- * @param sourceBean The bean to be given as the source for any events.
- * @exception NullPointerException if sourceBean is null
- */
-
- public PropertyChangeMulticaster(Object sourceBean) {
- if (sourceBean == null) {
- throw new NullPointerException();
- }
-
- source = sourceBean;
- }
-
- /**
- * Add a VetoableChangeListener to the listener list.
- * The listener is registered for all properties.
- * If the listener is added multiple times, it will
- * receive multiple change notifications upon any firePropertyChange
- *
- * @param listener The PropertyChangeListener to be added
- * @exception NullPointerException If listener is null
- */
-
- public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
-
- if (listener == null) throw new NullPointerException();
-
- int len = listeners.length;
- PropertyChangeListener[] newArray = new PropertyChangeListener[len + 1];
- if (len > 0)
- System.arraycopy(listeners, 0, newArray, 0, len);
- newArray[len] = listener;
- listeners = newArray;
- }
-
-
- /**
- * Add a PropertyChangeListener to the listener list if it is
- * not already present.
- * The listener is registered for all properties.
- * The operation maintains Set semantics: If the listener is already
- * registered, the operation has no effect.
- *
- * @param listener The PropertyChangeListener to be added
- * @exception NullPointerException If listener is null
- */
-
- public synchronized void addPropertyChangeListenerIfAbsent(PropertyChangeListener listener) {
-
- if (listener == null) throw new NullPointerException();
-
- // Copy while checking if already present.
- int len = listeners.length;
- PropertyChangeListener[] newArray = new PropertyChangeListener[len + 1];
- for (int i = 0; i < len; ++i) {
- newArray[i] = listeners[i];
- if (listener.equals(listeners[i]))
- return; // already present -- throw away copy
- }
- newArray[len] = listener;
- listeners = newArray;
- }
-
-
- /**
- * Remove a PropertyChangeListener from the listener list.
- * It removes at most one occurrence of the given listener.
- * If the listener was added multiple times it must be removed
- * mulitple times.
- * This removes a PropertyChangeListener that was registered
- * for all properties, and has no effect if registered for only
- * one or more specified properties.
- *
- * @param listener The PropertyChangeListener to be removed
- */
-
- public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
-
- int newlen = listeners.length-1;
- if (newlen < 0 || listener == null) return;
-
- // Copy while searching for element to remove
-
- PropertyChangeListener[] newArray = new PropertyChangeListener[newlen];
-
- for (int i = 0; i < newlen; ++i) {
- if (listener.equals(listeners[i])) {
- // copy remaining and exit
- for (int k = i + 1; k <= newlen; ++k) newArray[k-1] = listeners[k];
- listeners = newArray;
- return;
- }
- else
- newArray[i] = listeners[i];
- }
-
- // special-case last cell
- if (listener.equals(listeners[newlen]))
- listeners = newArray;
- }
-
- /**
- * Add a PropertyChangeListener for a specific property. The listener
- * will be invoked only when a call on firePropertyChange names that
- * specific property. However, if a listener is registered both for all
- * properties and a specific property, it will receive multiple
- * notifications upon changes to that property.
- *
- * @param propertyName The name of the property to listen on.
- * @param listener The PropertyChangeListener to be added
- * @exception NullPointerException If listener is null
- */
-
- public void addPropertyChangeListener(String propertyName,
- PropertyChangeListener listener) {
-
- if (listener == null) throw new NullPointerException();
-
- PropertyChangeMulticaster child = null;
-
- synchronized(this) {
- if (children == null)
- children = new HashMap();
- else
- child = (PropertyChangeMulticaster)children.get(propertyName);
-
- if (child == null) {
- child = new PropertyChangeMulticaster(source);
- children.put(propertyName, child);
- }
- }
-
- child.addPropertyChangeListener(listener);
- }
-
- /**
- * Add a PropertyChangeListener for a specific property, if it is not
- * already registered. The listener
- * will be invoked only when a call on firePropertyChange names that
- * specific property.
- *
- * @param propertyName The name of the property to listen on.
- * @param listener The PropertyChangeListener to be added
- * @exception NullPointerException If listener is null
- */
-
- public void addPropertyChangeListenerIfAbsent(String propertyName,
- PropertyChangeListener listener) {
-
- if (listener == null) throw new NullPointerException();
-
- PropertyChangeMulticaster child = null;
-
- synchronized(this) {
- if (children == null)
- children = new HashMap();
- else
- child = (PropertyChangeMulticaster)children.get(propertyName);
-
- if (child == null) {
- child = new PropertyChangeMulticaster(source);
- children.put(propertyName, child);
- }
- }
-
- child.addPropertyChangeListenerIfAbsent(listener);
- }
-
- /**
- * Remove a PropertyChangeListener for a specific property.
- * Affects only the given property.
- * If the listener is also registered for all properties,
- * then it will continue to be registered for them.
- *
- * @param propertyName The name of the property that was listened on.
- * @param listener The PropertyChangeListener to be removed
- */
-
- public void removePropertyChangeListener(String propertyName,
- PropertyChangeListener listener) {
-
- PropertyChangeMulticaster child = getChild(propertyName);
- if (child != null)
- child.removePropertyChangeListener(listener);
- }
-
-
- /**
- * Helper method to relay evt to all listeners.
- * Called by all public firePropertyChange methods.
- **/
-
- protected void multicast(PropertyChangeEvent evt) {
-
- PropertyChangeListener[] array; // bind in synch block below
- PropertyChangeMulticaster child = null;
-
- synchronized (this) {
- array = listeners;
-
- if (children != null && evt.getPropertyName() != null)
- child = (PropertyChangeMulticaster)children.get(evt.getPropertyName());
- }
-
- for (int i = 0; i < array.length; ++i)
- array[i].propertyChange(evt);
-
- if (child != null)
- child.multicast(evt);
-
- }
-
-
- /**
- * Report a bound property update to any registered listeners.
- * No event is fired if old and new are equal and non-null.
- *
- * @param propertyName The programmatic name of the property
- * that was changed.
- * @param oldValue The old value of the property.
- * @param newValue The new value of the property.
- */
- public void firePropertyChange(String propertyName,
- Object oldValue, Object newValue) {
-
- if (oldValue == null || newValue == null || !oldValue.equals(newValue)) {
- multicast(new PropertyChangeEvent(source,
- propertyName,
- oldValue,
- newValue));
- }
-
- }
-
- /**
- * Report an int bound property update to any registered listeners.
- * No event is fired if old and new are equal and non-null.
- * <p>
- * This is merely a convenience wrapper around the more general
- * firePropertyChange method that takes Object values.
- *
- * @param propertyName The programmatic name of the property
- * that was changed.
- * @param oldValue The old value of the property.
- * @param newValue The new value of the property.
- */
- public void firePropertyChange(String propertyName,
- int oldValue, int newValue) {
- if (oldValue != newValue) {
- multicast(new PropertyChangeEvent(source,
- propertyName,
- Integer.valueOf(oldValue),
- Integer.valueOf(newValue)));
- }
- }
-
-
- /**
- * Report a boolean bound property update to any registered listeners.
- * No event is fired if old and new are equal and non-null.
- * <p>
- * This is merely a convenience wrapper around the more general
- * firePropertyChange method that takes Object values.
- *
- * @param propertyName The programmatic name of the property
- * that was changed.
- * @param oldValue The old value of the property.
- * @param newValue The new value of the property.
- */
- public void firePropertyChange(String propertyName,
- boolean oldValue, boolean newValue) {
- if (oldValue != newValue) {
- multicast(new PropertyChangeEvent(source,
- propertyName,
- Boolean.valueOf(oldValue), // GemStoneAddition
- Boolean.valueOf(newValue))); // GemStoneAddition
- }
- }
-
- /**
- * Fire an existing PropertyChangeEvent to any registered listeners.
- * No event is fired if the given event's old and new values are
- * equal and non-null.
- * @param evt The PropertyChangeEvent object.
- */
- public void firePropertyChange(PropertyChangeEvent evt) {
- Object oldValue = evt.getOldValue();
- Object newValue = evt.getNewValue();
- if (oldValue == null || newValue == null || !oldValue.equals(newValue))
- multicast(evt);
- }
-
- /**
- * Check if there are any listeners for a specific property.
- * If propertyName is null, return whether there are any listeners at all.
- *
- * @param propertyName the property name.
- * @return true if there are one or more listeners for the given property
- *
- */
- public boolean hasListeners(String propertyName) {
-
- PropertyChangeMulticaster child;
-
- synchronized (this) {
- if (listeners.length > 0)
- return true;
- else if (propertyName == null || children == null)
- return false;
- else {
- child = (PropertyChangeMulticaster)children.get(propertyName);
- if (child == null)
- return false;
- }
- }
-
- return child.hasListeners(null);
- }
-
-
- /**
- * @serialData Null terminated list of <code>PropertyChangeListeners</code>.
- * <p>
- * At serialization time we skip non-serializable listeners and
- * only serialize the serializable listeners.
- *
- */
- private synchronized void writeObject(ObjectOutputStream s) throws IOException {
- s.defaultWriteObject();
-
- for (int i = 0; i < listeners.length; i++) {
-// PropertyChangeListener l = listeners[i]; GemStoneAddition
- if (listeners[i] instanceof Serializable) {
- s.writeObject(listeners[i]);
- }
- }
- s.writeObject(null);
- }
-
-
- private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
- listeners = new PropertyChangeListener[0]; // paranoically reset
- s.defaultReadObject();
-
- Object listenerOrNull;
- while (null != (listenerOrNull = s.readObject())) {
- addPropertyChangeListener((PropertyChangeListener)listenerOrNull);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/Puttable.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/Puttable.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/Puttable.java
deleted file mode 100644
index a1d1e75..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/Puttable.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: Puttable.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-/**
- * This interface exists to enable stricter type checking
- * for channels. A method argument or instance variable
- * in a producer object can be declared as only a Puttable
- * rather than a Channel, in which case a Java compiler
- * will disallow take operations.
- * <p>
- * Full method descriptions appear in the Channel interface.
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- * @see Channel
- * @see Takable
-**/
-
-public interface Puttable {
-
-
- /**
- * Place item in the channel, possibly waiting indefinitely until
- * it can be accepted. Channels implementing the BoundedChannel
- * subinterface are generally guaranteed to block on puts upon
- * reaching capacity, but other implementations may or may not block.
- * @param item the element to be inserted. Should be non-null.
- * @exception InterruptedException if the current thread has
- * been interrupted at a point at which interruption
- * is detected, in which case the element is guaranteed not
- * to be inserted. Otherwise, on normal return, the element is guaranteed
- * to have been inserted.
- **/
- public void put(Object item) throws InterruptedException;
-
-
- /**
- * Place item in channel only if it can be accepted within
- * msecs milliseconds. The time bound is interpreted in
- * a coarse-grained, best-effort fashion.
- * @param item the element to be inserted. Should be non-null.
- * @param msecs the number of milliseconds to wait. If less than
- * or equal to zero, the method does not perform any timed waits,
- * but might still require
- * access to a synchronization lock, which can impose unbounded
- * delay if there is a lot of contention for the channel.
- * @return true if accepted, else false
- * @exception InterruptedException if the current thread has
- * been interrupted at a point at which interruption
- * is detected, in which case the element is guaranteed not
- * to be inserted (i.e., is equivalent to a false return).
- **/
- public boolean offer(Object item, long msecs) throws InterruptedException;
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedExecutor.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedExecutor.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedExecutor.java
deleted file mode 100644
index 8042d90..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedExecutor.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: QueuedExecutor.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 21Jun1998 dl Create public version
- 28aug1998 dl rely on ThreadFactoryUser, restart now public
- 4may1999 dl removed redundant interrupt detect
- 7sep2000 dl new shutdown methods
- 20may2004 dl can shutdown even if thread not created yet
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-
-/**
- *
- * An implementation of Executor that queues incoming
- * requests until they can be processed by a single background
- * thread.
- * <p>
- * The thread is not actually started until the first
- * <code>execute</code> request is encountered. Also, if the
- * thread is stopped for any reason (for example, after hitting
- * an unrecoverable exception in an executing task), one is started
- * upon encountering a new request, or if <code>restart()</code> is
- * invoked.
- * <p>
- * Beware that, especially in situations
- * where command objects themselves invoke execute, queuing can
- * sometimes lead to lockups, since commands that might allow
- * other threads to terminate do not run at all when they are in the queue.
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- **/
-public class QueuedExecutor extends ThreadFactoryUser implements Executor {
-
-
-
- /** The thread used to process commands **/
- protected Thread thread_;
-
- /** Special queue element to signal termination **/
- protected final/*GemStoneAddition*/ static Runnable ENDTASK = new Runnable() { public void run() {} };
-
- /** true if thread should shut down after processing current task **/
- protected volatile boolean shutdown_; // latches true;
-
- /**
- * Return the thread being used to process commands, or
- * null if there is no such thread. You can use this
- * to invoke any special methods on the thread, for
- * example, to interrupt it.
- **/
- public synchronized Thread getThread() {
- return thread_;
- }
-
- /** set thread_ to null to indicate termination **/
- protected synchronized void clearThread() {
- thread_ = null;
- }
-
-
- /** The queue **/
- protected final Channel queue_;
-
-
- /**
- * The runloop is isolated in its own Runnable class
- * just so that the main
- * class need not implement Runnable, which would
- * allow others to directly invoke run, which would
- * never make sense here.
- **/
- protected class RunLoop implements Runnable {
- public void run() {
- try {
- while (!shutdown_) {
- Runnable task = (Runnable)(queue_.take());
- if (task == ENDTASK) {
- shutdown_ = true;
- break;
- }
- else if (task != null) {
- task.run();
- task = null;
- }
- else
- break;
- }
- }
- catch (InterruptedException ex) {
- Thread.currentThread().interrupt(); // GemStoneAddition
- } // fallthrough
- finally {
- clearThread();
- }
- }
- }
-
- protected final RunLoop runLoop_;
-
-
- /**
- * Construct a new QueuedExecutor that uses
- * the supplied Channel as its queue.
- * <p>
- * This class does not support any methods that
- * reveal this queue. If you need to access it
- * independently (for example to invoke any
- * special status monitoring operations), you
- * should record a reference to it separately.
- **/
-
- public QueuedExecutor(Channel queue) {
- queue_ = queue;
- runLoop_ = new RunLoop();
- }
-
- /**
- * Construct a new QueuedExecutor that uses
- * a BoundedLinkedQueue with the current
- * DefaultChannelCapacity as its queue.
- **/
-
- public QueuedExecutor() {
- this(new BoundedLinkedQueue());
- }
-
- /**
- * Start (or restart) the background thread to process commands. It has
- * no effect if a thread is already running. This
- * method can be invoked if the background thread crashed
- * due to an unrecoverable exception.
- **/
-
- public synchronized void restart() {
- if (thread_ == null && !shutdown_) {
- thread_ = threadFactory_.newThread(runLoop_);
- thread_.start();
- }
- }
-
-
- /**
- * Arrange for execution of the command in the
- * background thread by adding it to the queue.
- * The method may block if the channel's put
- * operation blocks.
- * <p>
- * If the background thread
- * does not exist, it is created and started.
- **/
- public void execute(Runnable command) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- restart();
- queue_.put(command);
- }
-
- /**
- * Terminate background thread after it processes all
- * elements currently in queue. Any tasks entered after this point will
- * not be processed. A shut down thread cannot be restarted.
- * This method may block if the task queue is finite and full.
- * Also, this method
- * does not in general apply (and may lead to comparator-based
- * exceptions) if the task queue is a priority queue.
- **/
- public synchronized void shutdownAfterProcessingCurrentlyQueuedTasks() {
- if (!shutdown_) {
- try { queue_.put(ENDTASK); }
- catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
- }
-
-
- /**
- * Terminate background thread after it processes the
- * current task, removing other queued tasks and leaving them unprocessed.
- * A shut down thread cannot be restarted.
- **/
- public synchronized void shutdownAfterProcessingCurrentTask() {
- shutdown_ = true;
- try {
- while (queue_.poll(0) != null) ; // drain
- queue_.put(ENDTASK);
- }
- catch (InterruptedException ex) {
- Thread.currentThread().interrupt();
- }
- }
-
-
- /**
- * Terminate background thread even if it is currently processing
- * a task. This method uses Thread.interrupt, so relies on tasks
- * themselves responding appropriately to interruption. If the
- * current tasks does not terminate on interruption, then the
- * thread will not terminate until processing current task.
- * A shut down thread cannot be restarted.
- **/
- public synchronized void shutdownNow() {
- shutdown_ = true;
- Thread t = thread_;
- if (t != null)
- t.interrupt();
- shutdownAfterProcessingCurrentTask();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedSemaphore.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedSemaphore.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedSemaphore.java
deleted file mode 100644
index 470dd0d..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/QueuedSemaphore.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: QueuedSemaphore.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
- 5Aug1998 dl replaced int counters with longs
- 24Aug1999 dl release(n): screen arguments
-*/
-
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-/**
- * Abstract base class for semaphores relying on queued wait nodes.
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
-**/
-
-
-public abstract class QueuedSemaphore extends Semaphore {
-
- protected final WaitQueue wq_;
-
- QueuedSemaphore(WaitQueue q, long initialPermits) {
- super(initialPermits);
- wq_ = q;
- }
-
- @Override // GemStoneAddition
- public void acquire() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- if (precheck()) return;
- WaitQueue.WaitNode w = new WaitQueue.WaitNode();
- w.doWait(this);
- }
-
- @Override // GemStoneAddition
- public boolean attempt(long msecs) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- if (precheck()) return true;
- if (msecs <= 0) return false;
-
- WaitQueue.WaitNode w = new WaitQueue.WaitNode();
- return w.doTimedWait(this, msecs);
- }
-
- protected synchronized boolean precheck() {
- boolean pass = (permits_ > 0);
- if (pass) --permits_;
- return pass;
- }
-
- protected synchronized boolean recheck(WaitQueue.WaitNode w) {
- boolean pass = (permits_ > 0);
- if (pass) --permits_;
- else wq_.insert(w);
- return pass;
- }
-
-
- protected synchronized WaitQueue.WaitNode getSignallee() {
- WaitQueue.WaitNode w = wq_.extract();
- if (w == null) ++permits_; // if none, inc permits for new arrivals
- return w;
- }
-
- @Override // GemStoneAddition
- public void release() {
- for (;;) {
- WaitQueue.WaitNode w = getSignallee();
- if (w == null) return; // no one to signal
- if (w.signal()) return; // notify if still waiting, else skip
- }
- }
-
- /** Release N permits **/
- @Override // GemStoneAddition
- public void release(long n) {
- if (n < 0) throw new IllegalArgumentException("Negative argument");
-
- for (long i = 0; i < n; ++i) release();
- }
-
- /**
- * Base class for internal queue classes for semaphores, etc.
- * Relies on subclasses to actually implement queue mechanics
- **/
-
- protected static abstract class WaitQueue {
-
- protected abstract void insert(WaitNode w);// assumed not to block
- protected abstract WaitNode extract(); // should return null if empty
-
- protected static class WaitNode {
- boolean waiting = true;
- WaitNode next = null;
-
- protected synchronized boolean signal() {
- boolean signalled = waiting;
- if (signalled) {
- waiting = false;
- notify();
- }
- return signalled;
- }
-
- protected synchronized boolean doTimedWait(QueuedSemaphore sem,
- long msecs)
- throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- if (sem.recheck(this) || !waiting)
- return true;
- else if (msecs <= 0) {
- waiting = false;
- return false;
- }
- else {
- long waitTime = msecs;
- long start = System.currentTimeMillis();
-
- try {
- for (;;) {
- wait(waitTime);
- if (!waiting) // definitely signalled
- return true;
- else {
- waitTime = msecs - (System.currentTimeMillis() - start);
- if (waitTime <= 0) { // timed out
- waiting = false;
- return false;
- }
- }
- }
- }
- catch(InterruptedException ex) {
- if (waiting) { // no notification
- waiting = false; // invalidate for the signaller
- throw ex;
- }
- else { // thread was interrupted after it was notified
- Thread.currentThread().interrupt();
- return true;
- }
- }
- }
- }
-
- protected synchronized void doWait(QueuedSemaphore sem)
- throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException(); // GemStoneAddition
- if (!sem.recheck(this)) {
- try {
- while (waiting) wait();
- }
- catch(InterruptedException ex) {
- if (waiting) { // no notification
- waiting = false; // invalidate for the signaller
- throw ex;
- }
- else { // thread was interrupted after it was notified
- Thread.currentThread().interrupt();
- return;
- }
- }
- }
- }
- }
-
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReadWriteLock.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReadWriteLock.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReadWriteLock.java
deleted file mode 100644
index 2a84a51..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReadWriteLock.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: ReadWriteLock.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
-*/
-
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-
-/**
- * ReadWriteLocks maintain a pair of associated locks.
- * The readLock may be held simultanously by multiple
- * reader threads, so long as there are no writers. The writeLock
- * is exclusive. ReadWrite locks are generally preferable to
- * plain Sync locks or synchronized methods in cases where:
- * <ul>
- * <li> The methods in a class can be cleanly separated into
- * those that only access (read) data vs those that
- * modify (write).
- * <li> Target applications generally have more readers than writers.
- * <li> The methods are relatively time-consuming (as a rough
- * rule of thumb, exceed more than a hundred instructions), so it
- * pays to introduce a bit more overhead associated with
- * ReadWrite locks compared to simple synchronized methods etc
- * in order to allow concurrency among reader threads.
- *
- * </ul>
- * Different implementation classes differ in policies surrounding
- * which threads to prefer when there is
- * contention. By far, the most commonly useful policy is
- * WriterPreferenceReadWriteLock. The other implementations
- * are targeted for less common, niche applications.
- *<p>
- * Standard usage:
- * <pre>
- * class X {
- * ReadWriteLock rw;
- * // ...
- *
- * public void read() throws InterruptedException {
- * rw.readLock().acquire();
- * try {
- * // ... do the read
- * }
- * finally {
- * rw.readlock().release()
- * }
- * }
- *
- *
- * public void write() throws InterruptedException {
- * rw.writeLock().acquire();
- * try {
- * // ... do the write
- * }
- * finally {
- * rw.writelock().release()
- * }
- * }
- * }
- * </pre>
- * @see Sync
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
-
-**/
-
-public interface ReadWriteLock {
- /** get the readLock **/
- Sync readLock();
-
- /** get the writeLock **/
- Sync writeLock();
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReaderPreferenceReadWriteLock.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReaderPreferenceReadWriteLock.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReaderPreferenceReadWriteLock.java
deleted file mode 100644
index 4592ff7..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReaderPreferenceReadWriteLock.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: ReaderPreferenceReadWriteLock.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-/**
- * A ReadWriteLock that prefers waiting readers over
- * waiting writers when there is contention. The range of applicability
- * of this class is very limited. In the majority of situations,
- * writer preference locks provide more reasonable semantics.
- *
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- **/
-
-public class ReaderPreferenceReadWriteLock extends WriterPreferenceReadWriteLock {
- @Override // GemStoneAddition
- protected boolean allowReader() {
- return activeWriter_ == null;
- }
-}
-
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8b2ea77d/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReentrantLock.java
----------------------------------------------------------------------
diff --git a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReentrantLock.java b/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReentrantLock.java
deleted file mode 100644
index bf58aa3..0000000
--- a/gemfire-jgroups/src/main/java/com/gemstone/org/jgroups/oswego/concurrent/ReentrantLock.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/** Notice of modification as required by the LGPL
- * This file was modified by Gemstone Systems Inc. on
- * $Date$
- **/
-/*
- File: ReentrantLock.java
-
- Originally written by Doug Lea and released into the public domain.
- This may be used for any purposes whatsoever without acknowledgment.
- Thanks for the assistance and support of Sun Microsystems Labs,
- and everyone contributing, testing, and using this code.
-
- History:
- Date Who What
- 11Jun1998 dl Create public version
- 5Aug1998 dl replaced int counters with longs
-*/
-
-package com.gemstone.org.jgroups.oswego.concurrent;
-
-/**
- * A lock with the same semantics as builtin
- * Java synchronized locks: Once a thread has a lock, it
- * can re-obtain it any number of times without blocking.
- * The lock is made available to other threads when
- * as many releases as acquires have occurred.
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
-**/
-
-
-public class ReentrantLock implements Sync {
-
- protected Thread owner_ = null;
- protected long holds_ = 0;
-
- public void acquire() throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Thread caller = Thread.currentThread();
- synchronized(this) {
- if (caller == owner_)
- ++holds_;
- else {
- try {
- while (owner_ != null) wait();
- owner_ = caller;
- holds_ = 1;
- }
- catch (InterruptedException ex) {
- notify();
- throw ex;
- }
- }
- }
- }
-
-
- public boolean attempt(long msecs) throws InterruptedException {
- if (Thread.interrupted()) throw new InterruptedException();
- Thread caller = Thread.currentThread();
- synchronized(this) {
- if (caller == owner_) {
- ++holds_;
- return true;
- }
- else if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else if (msecs <= 0)
- return false;
- else {
- long waitTime = msecs;
- long start = System.currentTimeMillis();
- try {
- for (;;) {
- wait(waitTime);
- if (caller == owner_) {
- ++holds_;
- return true;
- }
- else if (owner_ == null) {
- owner_ = caller;
- holds_ = 1;
- return true;
- }
- else {
- waitTime = msecs - (System.currentTimeMillis() - start);
- if (waitTime <= 0)
- return false;
- }
- }
- }
- catch (InterruptedException ex) {
- notify();
- throw ex;
- }
- }
- }
- }
-
- /**
- * Release the lock.
- * @exception Error thrown if not current owner of lock
- **/
- public synchronized void release() {
- if (Thread.currentThread() != owner_)
- throw new Error("Illegal Lock usage");
-
- if (--holds_ == 0) {
- owner_ = null;
- notify();
- }
- }
-
- /**
- * Release the lock N times. <code>release(n)</code> is
- * equivalent in effect to:
- * <pre>
- * for (int i = 0; i < n; ++i) release();
- * </pre>
- * <p>
- * @exception Error thrown if not current owner of lock
- * or has fewer than N holds on the lock
- **/
- public synchronized void release(long n) {
- if (Thread.currentThread() != owner_ || n > holds_)
- throw new Error("Illegal Lock usage");
-
- holds_ -= n;
- if (holds_ == 0) {
- owner_ = null;
- notify();
- }
- }
-
-
- /**
- * Return the number of unreleased acquires performed
- * by the current thread.
- * Returns zero if current thread does not hold lock.
- **/
- public synchronized long holds() {
- if (Thread.currentThread() != owner_) return 0;
- return holds_;
- }
-
-
-
-}
-