* New instances of this thread pool are created by constructing and configuring a {@link Builder} instance, and calling
* its {@link Builder#build() build()} method.
*
* @author David M. Lloyd
*/
@Contended
public final class EnhancedQueueExecutor extends AbstractExecutorService implements ManageableThreadPoolExecutorService {
static {
Version.getVersionString();
}
/*
┌──────────────────────────┐
│ Explanation of operation │
└──────────────────────────┘
The primary mechanism of this executor is the special linked list/stack. This list has the following properties:
• Multiple node types:
◦ Task nodes (TaskNode), which have the following properties:
▪ Strongly connected (no task is ever removed from the middle of the list; tail can always be found by following .next pointers)
▪ FIFO (insertion at tail.next, "removal" at head.next)
▪ Head and tail always refer to TaskNodes; head.next/tail.next are the "true" action points for all node types
▪ At least one dead task node is always in the list, thus the task is cleared after execution to avoid leaks
◦ Waiting consumer thread nodes (PoolThreadNode), which have the following properties:
▪ LIFO/FILO (insertion and removal at tail.next)
▪ Carrier for task handoff between producer and waiting consumer
◦ Waiting termination (awaitTermination) thread nodes (TerminateWaiterNode), which have the following properties:
▪ Append-only (insertion at tail.next.next...next)
▪ All removed at once when termination is complete
▪ If a thread stops waiting, the node remains (but its thread field is cleared to prevent (best-effort) useless unparks)
▪ Once cleared, the thread field can never be reinitialized
• Concurrently accessed (multiple threads may read the list and update the head and tail pointers)
• TaskNode.next may be any node type or null
• PoolThreadNode.next may only be another PoolThreadNode or null
• TerminateWaiterNode.next may only be another TerminateWaiterNode or null
The secondary mechanism is the thread status atomic variable. It is logically a structure with the following fields:
• Current thread count (currentSizeOf(), withCurrentSize())
• Core pool size (coreSizeOf(), withCoreSize())
• Max pool size (maxSizeOf(), withMaxSize())
• Shutdown-requested flag (isShutdownRequested(), withShutdownRequested())
• Shutdown-with-interrupt requested flag (isShutdownInterrupt(), withShutdownInterrupt())
• Shutdown-completed flag (isShutdownComplete(), withShutdownComplete())
• The decision to create a new thread is affected by whether the number of active threads is less than the core size;
if not, then the growth resistance factor is applied to decide whether the task should be enqueued or a new thread begun.
Note: the default growth resistance factor is 0% resistance.
The final mechanism is the queue status atomic variable. It is logically a structure with the following fields:
• Current queue size (currentQueueSizeOf(), withCurrentQueueSize())
• Queue size limit (maxQueueSizeOf(), withMaxQueueSize())
*/
// =======================================================
// Optimization control flags
// =======================================================
/**
* A global hint which establishes whether it is recommended to disable uses of {@code EnhancedQueueExecutor}.
* This hint defaults to {@code false} but can be changed to {@code true} by setting the {@code jboss.threads.eqe.disable}
* property to {@code true} before this class is initialized.
*/
public static final boolean DISABLE_HINT = readBooleanProperty("disable", false);
/**
* Update the tail pointer opportunistically.
*/
static final boolean UPDATE_TAIL = readBooleanProperty("update-tail", false);
/**
* Update the summary statistics.
*/
static final boolean UPDATE_STATISTICS = readBooleanProperty("statistics", true);
/**
* Suppress queue limit and size tracking for performance.
*/
static final boolean NO_QUEUE_LIMIT = readBooleanProperty("unlimited-queue", false);
/**
* Establish a combined head/tail lock.
*/
static final boolean COMBINED_LOCK = readBooleanProperty("combined-lock", false);
/**
* Attempt to lock frequently-contended operations on the list tail. This defaults to {@code true} because
* moderate contention among 8 CPUs can result in thousands of spin misses per execution.
*/
static final boolean TAIL_LOCK = COMBINED_LOCK || readBooleanProperty("tail-lock", true);
/**
* Attempt to lock frequently-contended operations on the list head.
*/
static final boolean HEAD_LOCK = COMBINED_LOCK || readBooleanProperty("head-lock", true);
/**
* Set the default value for whether an mbean is to be auto-registered for the thread pool.
*/
static final boolean REGISTER_MBEAN = readBooleanProperty("register-mbean", true);
// =======================================================
// Constants
// =======================================================
static final Executor DEFAULT_HANDLER = JBossExecutors.rejectingExecutor();
// =======================================================
// Locks
// =======================================================
/**
* The tail lock. Only used if {@link #TAIL_LOCK} is {@code true}.
*/
final Object tailLock = new Object();
/**
* The head lock. Only used if {@link #HEAD_LOCK} is {@code true}.
*/
final Object headLock = COMBINED_LOCK ? tailLock : new Object();
// =======================================================
// Immutable configuration fields
// =======================================================
/**
* The thread factory.
*/
private final ThreadFactory threadFactory;
/**
* The approximate set of pooled threads.
*/
private final Set
* This method is named differently from the typical {@code allowsCoreThreadTimeOut()} in order to accommodate
* the requirements of MXBean attribute methods.
*
* @return {@code true} if core threads are allowed to time out, {@code false} otherwise
*/
boolean isAllowCoreThreadTimeOut();
/**
* Establish whether core threads are allowed to time out. A "core thread" is defined as any thread in the pool
* when the pool size is below the pool's {@linkplain #getCorePoolSize() core pool size}. If the thread pool
* does not support a separate core pool size, the value is ignored.
*
* This method is named differently from the typical {@code allowCoreThreadTimeOut(boolean)} in order to accommodate
* the requirements of MXBean attribute methods.
*
* @param value {@code true} if core threads are allowed to time out, {@code false} otherwise
*/
void setAllowCoreThreadTimeOut(boolean value);
/**
* Get the thread keep-alive time, in seconds.
*
* This method differs from the typical {@code getKeepAliveTime(TimeUnit)} due to the inability to send in a
* time units parameter on an MXBean attribute. As such, the unit is hard-coded to seconds.
*
* @return the thread keep-alive time, in seconds
*/
long getKeepAliveTimeSeconds();
/**
* Set the thread keep-alive time, in seconds.
*
* This method differs from the typical {@code getKeepAliveTime(TimeUnit)} due to the inability to send in a
* time units parameter on an MXBean attribute. As such, the unit is hard-coded to seconds.
*
* @param seconds the thread keep-alive time, in seconds (must be greater than or equal to 0)
*/
void setKeepAliveTimeSeconds(long seconds);
/**
* Get the maximum queue size for this thread pool. If there is no queue or it is not bounded, {@link Integer#MAX_VALUE} is
* returned.
*
* @return the maximum queue size
*/
int getMaximumQueueSize();
/**
* Set the maximum queue size for this thread pool. If the new maximum queue size is smaller than the current queue
* size, there is no effect other than preventing tasks from being enqueued until the size decreases below the
* maximum again. If changing the maximum queue size is not supported, or there is no bounded backing queue,
* then the value is ignored.
*
* @param size the maximum queue size for this thread pool
*/
void setMaximumQueueSize(int size);
/**
* Get an estimate of the current queue size, if any. If no backing queue exists, or its size cannot be determined,
* this method will return 0.
*
* @return an estimate of the current queue size
*/
int getQueueSize();
/**
* Get an estimate of the peak size of the queue, if any. If no backing queue exists, or its size cannot be determined,
* this method will return 0.
*
* @return an estimate of the peak size of the queue
*/
int getLargestQueueSize();
/**
* Determine whether there is a bounded queue backing this thread pool.
*
* @return {@code true} if there is a bounded backing queue, {@code false} otherwise
*/
boolean isQueueBounded();
/**
* Determine whether the maximum queue size is modifiable.
*
* @return {@code true} if the queue size is modifiable, false otherwise
*/
boolean isQueueSizeModifiable();
/**
* Determine whether shutdown was requested.
*
* @return {@code true} if shutdown was requested, {@code false} otherwise
*/
boolean isShutdown();
/**
* Determine whether shutdown is in progress.
*
* @return {@code true} if shutdown is in progress, {@code false} otherwise
*/
boolean isTerminating();
/**
* Determine whether shutdown is complete.
*
* @return {@code true} if shutdown is complete, {@code false} otherwise
*/
boolean isTerminated();
/**
* Get an estimate of the total number of tasks ever submitted to this thread pool. This number may be zero
* if the underlying thread pool does not support this metric.
*
* @return an estimate of the total number of tasks ever submitted to this thread pool
*/
long getSubmittedTaskCount();
/**
* Get an estimate of the total number of tasks ever rejected by this thread pool for any reason. This number may be zero
* if the underlying thread pool does not support this metric.
*
* @return an estimate of the total number of tasks ever rejected by this thread pool
*/
long getRejectedTaskCount();
/**
* Get an estimate of the number of tasks completed by this thread pool. This number may be zero
* if the underlying thread pool does not support this metric.
*
* @return an estimate of the number of tasks completed by this thread pool
*/
long getCompletedTaskCount();
/**
* Get the number of spin misses that have occurred. Spin misses indicate that contention is not being properly
* handled by the thread pool.
*
* @return an estimate of the number of spin misses
*/
default long getSpinMissCount() {
return 0;
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management/ThreadExecutorMBean.java 0000664 0000000 0000000 00000001645 13252743601 0032134 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads.management;
/**
*
*/
@Deprecated
public interface ThreadExecutorMBean {
int getRejectedCount();
int getCurrentThreadCount();
int getLargestThreadCount();
int getQueueSize();
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management/ThreadPoolExecutorMBean.java 0000664 0000000 0000000 00000001727 13252743601 0032767 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads.management;
/**
*
*/
@Deprecated
public interface ThreadPoolExecutorMBean extends ThreadExecutorMBean {
int getMaxThreads();
void setMaxThreads(int newSize);
long getKeepAliveTime();
void setKeepAliveTime(long milliseconds);
}
jboss-threads-2.3.2.Final/src/test/ 0000775 0000000 0000000 00000000000 13252743601 0017067 5 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/test/java/ 0000775 0000000 0000000 00000000000 13252743601 0020010 5 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/test/java/org/ 0000775 0000000 0000000 00000000000 13252743601 0020577 5 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/test/java/org/jboss/ 0000775 0000000 0000000 00000000000 13252743601 0021717 5 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/test/java/org/jboss/threads/ 0000775 0000000 0000000 00000000000 13252743601 0023351 5 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/test/java/org/jboss/threads/ArrayQueueTestCase.java 0000664 0000000 0000000 00000006526 13252743601 0027744 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import junit.framework.TestCase;
/**
*
*/
public final class ArrayQueueTestCase extends TestCase {
public void testBasic() {
final int max = 40;
final ArrayQueue
*
*/
@SuppressWarnings("unused") // used by field updater
volatile long queueSize;
/**
* Active consumers:
*
*
*/
@SuppressWarnings("unused") // used by field updater
volatile long threadStatus;
/**
* The thread keep-alive timeout value.
*/
volatile long timeoutNanos;
/**
* A resistance factor applied after the core pool is full; values applied here will cause that fraction
* of submissions to create new threads when no idle thread is available. A value of {@code 0.0f} implies that
* threads beyond the core size should be created as aggressively as threads within it; a value of {@code 1.0f}
* implies that threads beyond the core size should never be created.
*/
volatile float growthResistance;
/**
* The handler for tasks which cannot be accepted by the executor.
*/
volatile Executor handoffExecutor;
/**
* The handler for uncaught exceptions which occur during user tasks.
*/
volatile Thread.UncaughtExceptionHandler exceptionHandler;
/**
* The termination task to execute when the thread pool exits.
*/
volatile Runnable terminationTask;
// =======================================================
// Statistics fields and counters
// =======================================================
/**
* The peak number of threads ever created by this pool.
*/
@SuppressWarnings("unused") // used by field updater
volatile int peakThreadCount;
/**
* The approximate peak queue size.
*/
@SuppressWarnings("unused") // used by field updater
volatile int peakQueueSize;
private final LongAdder submittedTaskCounter = new LongAdder();
private final LongAdder completedTaskCounter = new LongAdder();
private final LongAdder rejectedTaskCounter = new LongAdder();
private final LongAdder spinMisses = new LongAdder();
/**
* The current active number of threads.
*/
@SuppressWarnings("unused")
volatile int activeCount;
// =======================================================
// Updaters
// =======================================================
private static final AtomicReferenceFieldUpdater(cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public ExecutionInterruptedException(final Throwable cause) {
super(cause);
}
/**
* Constructs a {@code ExecutionInterruptedException} with the specified detail message and cause.
*
* @param msg the detail message
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public ExecutionInterruptedException(final String msg, final Throwable cause) {
super(msg, cause);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ExecutionTimedOutException.java 0000664 0000000 0000000 00000005001 13252743601 0031452 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.concurrent.RejectedExecutionException;
/**
* Thrown when an execute-with-timeout method is called and the timeout elapsed before a task could be accepted.
*/
@Deprecated
public class ExecutionTimedOutException extends RejectedExecutionException {
private static final long serialVersionUID = 6577491781534695133L;
/**
* Constructs a {@code ExecutionTimedOutException} with no detail message. The cause is not initialized, and may
* subsequently be initialized by a call to {@link #initCause(Throwable) initCause}.
*/
public ExecutionTimedOutException() {
}
/**
* Constructs a {@code ExecutionTimedOutException} with the specified detail message. The cause is not initialized, and
* may subsequently be initialized by a call to {@link #initCause(Throwable) initCause}.
*
* @param msg the detail message
*/
public ExecutionTimedOutException(final String msg) {
super(msg);
}
/**
* Constructs a {@code ExecutionTimedOutException} with the specified cause. The detail message is set to:
* (cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public ExecutionTimedOutException(final Throwable cause) {
super(cause);
}
/**
* Constructs a {@code ExecutionTimedOutException} with the specified detail message and cause.
*
* @param msg the detail message
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public ExecutionTimedOutException(final String msg, final Throwable cause) {
super(msg, cause);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ExecutorTask.java 0000664 0000000 0000000 00000002236 13252743601 0026605 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
class ExecutorTask implements Runnable {
private final DirectExecutor executor;
private final Runnable task;
ExecutorTask(final DirectExecutor executor, final Runnable task) {
this.executor = executor;
this.task = task;
}
public void run() {
executor.execute(task);
}
public String toString() {
return String.format("%s (Task %s via %s)", super.toString(), task, executor);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/HandoffRejectedExecutionHandler.java 0000664 0000000 0000000 00000002446 13252743601 0032364 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
class HandoffRejectedExecutionHandler implements RejectedExecutionHandler {
private final Executor target;
HandoffRejectedExecutionHandler(final Executor target) {
this.target = target;
}
public void rejectedExecution(final Runnable r, final ThreadPoolExecutor executor) {
target.execute(r);
}
public String toString() {
return String.format("%s -> %s", super.toString(), target);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/InitializingExecutor.java 0000664 0000000 0000000 00000002423 13252743601 0030333 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
class InitializingExecutor implements DirectExecutor {
private final Runnable initializer;
private final DirectExecutor delegate;
InitializingExecutor(final Runnable initializer, final DirectExecutor delegate) {
this.initializer = initializer;
this.delegate = delegate;
}
public void execute(final Runnable command) {
initializer.run();
delegate.execute(command);
}
public String toString() {
return String.format("%s (init task=%s) -> %s", super.toString(), initializer, delegate);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/InterruptHandler.java 0000664 0000000 0000000 00000002261 13252743601 0027454 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
/**
* A thread interrupt handler. Called when a thread's {@code interrupt()} method is invoked. The handler should
* not throw an exception; otherwise user code might end up in an unexpected state.
*/
public interface InterruptHandler {
/**
* Handle an interrupt condition on the given thread. This method should not throw an exception.
*
* @param thread the thread which was interrupted
*/
void handleInterrupt(Thread thread);
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/JBossExecutors.java 0000664 0000000 0000000 00000105654 13252743601 0027116 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.lang.reflect.Field;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ScheduledExecutorService;
import java.util.Collection;
import java.security.PrivilegedAction;
import java.security.AccessController;
import java.security.Permission;
import org.jboss.logging.Logger;
import org.wildfly.common.Assert;
import sun.misc.Unsafe;
/**
* JBoss thread- and executor-related utility and factory methods.
*/
public final class JBossExecutors {
private static final Logger THREAD_ERROR_LOGGER = Logger.getLogger("org.jboss.threads.errors");
private JBossExecutors() {}
private static final RuntimePermission MODIFY_THREAD_PERMISSION = new RuntimePermission("modifyThread");
private static final RuntimePermission COPY_CONTEXT_CLASSLOADER_PERMISSION = new RuntimePermission("copyClassLoader");
private static final DirectExecutorService DIRECT_EXECUTOR_SERVICE = new DelegatingDirectExecutorService(SimpleDirectExecutor.INSTANCE);
private static final DirectExecutorService REJECTING_EXECUTOR_SERVICE = new DelegatingDirectExecutorService(RejectingExecutor.INSTANCE);
private static final DirectExecutorService DISCARDING_EXECUTOR_SERVICE = new DelegatingDirectExecutorService(DiscardingExecutor.INSTANCE);
@Deprecated
private static final BlockingExecutor BLOCKING_DIRECT_EXECUTOR = new DelegatingDirectBlockingExecutor(SimpleDirectExecutor.INSTANCE);
@Deprecated
private static final BlockingExecutor BLOCKING_REJECTING_EXECUTOR = new DelegatingDirectBlockingExecutor(RejectingExecutor.INSTANCE);
@Deprecated
private static final BlockingExecutor BLOCKING_DISCARDING_EXECUTOR = new DelegatingDirectBlockingExecutor(DiscardingExecutor.INSTANCE);
// ==================================================
// DIRECT EXECUTORS
// ==================================================
/**
* Get the direct executor. This executor will immediately run any task it is given, and propagate back any
* run-time exceptions thrown.
*
* @return the direct executor instance
*/
public static DirectExecutor directExecutor() {
return SimpleDirectExecutor.INSTANCE;
}
/**
* Get the direct executor service. This executor will immediately run any task it is given, and propagate back any
* run-time exceptions thrown. It cannot be shut down.
*
* @return the direct executor service instance
*/
public static DirectExecutorService directExecutorService() {
return DIRECT_EXECUTOR_SERVICE;
}
/**
* Get the rejecting executor. This executor will reject any task submitted to it.
*
* @return the rejecting executor instance
*/
public static DirectExecutor rejectingExecutor() {
return RejectingExecutor.INSTANCE;
}
/**
* Get a rejecting executor. This executor will reject any task submitted to it with the given message.
*
* @param message the reject message
* @return the rejecting executor instance
*/
public static DirectExecutor rejectingExecutor(final String message) {
return new RejectingExecutor(message);
}
/**
* Get the rejecting executor service. This executor will reject any task submitted to it. It cannot be shut down.
*
* @return the rejecting executor service instance
*/
public static DirectExecutorService rejectingExecutorService() {
return REJECTING_EXECUTOR_SERVICE;
}
/**
* Get the rejecting executor service. This executor will reject any task submitted to it with the given message.
* It cannot be shut down.
*
* @param message the reject message
* @return the rejecting executor service instance
*/
public static DirectExecutorService rejectingExecutorService(final String message) {
return protectedDirectExecutorService(rejectingExecutor(message));
}
/**
* Get the discarding executor. This executor will silently discard any task submitted to it.
*
* @return the discarding executor instance
*/
public static DirectExecutor discardingExecutor() {
return DiscardingExecutor.INSTANCE;
}
/**
* Get the discarding executor service. This executor will silently discard any task submitted to it. It cannot
* be shut down.
*
* @return the discarding executor service instance
*/
public static DirectExecutorService discardingExecutorService() {
return DISCARDING_EXECUTOR_SERVICE;
}
/**
* Create a direct executor which runs with the privileges given by the current access control context.
*
* @param delegate the executor to delegate to at the privileged level
* @return the new direct executor
*/
public static DirectExecutor privilegedExecutor(final DirectExecutor delegate) {
return new PrivilegedExecutor(delegate);
}
/**
* Create a direct executor which runs tasks with the given context class loader.
*
* @param delegate the executor to delegate to
* @param taskClassLoader the context class loader to use
* @return the new direct executor
*/
public static DirectExecutor contextClassLoaderExecutor(final DirectExecutor delegate, final ClassLoader taskClassLoader) {
return new ContextClassLoaderExecutor(taskClassLoader, delegate);
}
/**
* Create a direct executor which changes the thread name for the duration of a task.
*
* @param delegate the executor to delegate to
* @param newName the thread name to use
* @return the new direct executor
*/
public static DirectExecutor threadNameExecutor(final DirectExecutor delegate, final String newName) {
return new ThreadNameExecutor(newName, delegate);
}
/**
* Create a direct executor which changes the thread name for the duration of a task using a formatted name.
* The thread must be a {@link JBossThread}.
*
* @param delegate the executor to delegate to
* @param newName the thread name to use
* @return the new direct executor
*/
public static DirectExecutor threadFormattedNameExecutor(final DirectExecutor delegate, final String newName) {
return new ThreadFormattedNameExecutor(newName, delegate);
}
/**
* Create a direct executor which adds a note to the thread name for the duration of a task.
*
* @param delegate the executor to delegate to
* @param notation the note to use
* @return the new direct executor
*/
public static DirectExecutor threadNameNotateExecutor(final DirectExecutor delegate, final String notation) {
return new ThreadNameNotatingExecutor(notation, delegate);
}
/**
* Create a direct executor which consumes and logs errors that are thrown.
*
* @param delegate the executor to delegate to
* @param log the logger to which exceptions are written at the {@code error} level
* @return the new direct executor
*/
public static DirectExecutor exceptionLoggingExecutor(final DirectExecutor delegate, final Logger log) {
return new ExceptionLoggingExecutor(delegate, log);
}
/**
* Create a direct executor which consumes and logs errors that are thrown.
*
* @param delegate the executor to delegate to
* @param log the logger to which exceptions are written
* @param level the level at which to log exceptions
* @return the new direct executor
*/
public static DirectExecutor exceptionLoggingExecutor(final DirectExecutor delegate, final Logger log, final Logger.Level level) {
return new ExceptionLoggingExecutor(delegate, log, level);
}
/**
* Create a direct executor which consumes and logs errors that are thrown to the default thread error category
* {@code "org.jboss.threads.errors"}.
*
* @param delegate the executor to delegate to
* @return the new direct executor
*/
public static DirectExecutor exceptionLoggingExecutor(final DirectExecutor delegate) {
return exceptionLoggingExecutor(delegate, THREAD_ERROR_LOGGER);
}
/**
* Create a direct executor which delegates tasks to the given executor, and then clears all thread-local
* data after each task completes (regardless of outcome). You must have the {@link RuntimePermission}{@code ("modifyThread")}
* permission to use this method.
*
* @param delegate the delegate direct executor
* @return a resetting executor
* @throws SecurityException if the caller does not have the {@link RuntimePermission}{@code ("modifyThread")} permission
*/
public static DirectExecutor resettingExecutor(final DirectExecutor delegate) throws SecurityException {
return cleanupExecutor(delegate, threadLocalResetter());
}
/**
* Create an executor which runs the given initialization task before running its given task.
*
* @param delegate the delegate direct executor
* @param initializer the initialization task
* @return an initializing executor
*/
public static DirectExecutor initializingExecutor(final DirectExecutor delegate, final Runnable initializer) {
return new InitializingExecutor(initializer, delegate);
}
/**
* Create an executor which runs the given cleanup task after running its given task.
*
* @param delegate the delegate direct executor
* @param cleaner the cleanup task
* @return an initializing executor
*/
public static DirectExecutor cleanupExecutor(final DirectExecutor delegate, final Runnable cleaner) {
return new CleanupExecutor(cleaner, delegate);
}
// ==================================================
// DIRECT BLOCKING EXECUTORS
// ==================================================
/**
* Get an executor which executes tasks in the current thread, which implements {@code BlockingExecutor}.
*
* @return the blocking direct executor
*/
@Deprecated
public static BlockingExecutor blockingDirectExecutor() {
return BLOCKING_DIRECT_EXECUTOR;
}
/**
* Get an executor which discards all tasks, which implements {@code BlockingExecutor}.
*
* @return the executor
*/
@Deprecated
public static BlockingExecutor blockingDiscardingExecutor() {
return BLOCKING_DISCARDING_EXECUTOR;
}
/**
* Get an executor which rejects all tasks, which implements {@code BlockingExecutor}.
*
* @return the executor
*/
@Deprecated
public static BlockingExecutor blockingRejectingExecutor() {
return BLOCKING_REJECTING_EXECUTOR;
}
// ==================================================
// EXECUTORS
// ==================================================
/**
* An executor which delegates to another executor, wrapping each task in a task wrapper.
*
* @param taskWrapper the task wrapper
* @param delegate the delegate executor
* @return a wrapping executor
*/
public static Executor wrappingExecutor(final DirectExecutor taskWrapper, final Executor delegate) {
return executor(wrappingExecutor(delegate), taskWrapper);
}
/**
* An executor which delegates to the given direct executor, but implements the blocking executor interface.
* Since direct executors always execute tasks in the current thread, no blocking is possible; therefore the
* methods of BlockingExecutors always succeed or fail instantly.
*
* @param delegate the delegate direct executor
* @return the blocking executor
*/
@Deprecated
public static BlockingExecutor directBlockingExecutor(final DirectExecutor delegate) {
return new DelegatingDirectBlockingExecutor(delegate);
}
/**
* Create a wrapping executor for a delegate executor which creates an {@link #executorTask(DirectExecutor, Runnable)} for
* each task.
*
* @param delegate the delegate executor
* @return the wrapping executor
*/
public static WrappingExecutor wrappingExecutor(final Executor delegate) {
return new DelegatingWrappingExecutor(delegate);
}
/**
* An executor which delegates to a wrapping executor, wrapping each task in a task wrapper.
*
* @param delegate the delegate executor
* @param taskWrapper the task wrapper
* @return a wrapping executor
*/
public static Executor executor(final WrappingExecutor delegate, final DirectExecutor taskWrapper) {
return new DelegatingWrappedExecutor(delegate, taskWrapper);
}
/**
* Create an executor that executes each task in a new thread.
*
* @param factory the thread factory to use
* @return the executor
* @deprecated Use {@link EnhancedQueueExecutor} instead.
*/
@Deprecated
public static BlockingExecutor threadFactoryExecutor(final ThreadFactory factory) {
return new ThreadFactoryExecutor(factory, Integer.MAX_VALUE, false, directExecutor());
}
/**
* Create an executor that executes each task in a new thread. By default up to the given number of threads may run
* concurrently, after which new tasks will be rejected.
*
* @param factory the thread factory to use
* @param maxThreads the maximum number of allowed threads
* @return the executor
* @deprecated Use {@link EnhancedQueueExecutor} instead.
*/
@Deprecated
public static BlockingExecutor threadFactoryExecutor(final ThreadFactory factory, final int maxThreads) {
return new ThreadFactoryExecutor(factory, maxThreads, false, directExecutor());
}
/**
* Create an executor that executes each task in a new thread. By default up to the given number of threads may run
* concurrently, after which the caller will block or new tasks will be rejected, according to the setting of the
* {@code blocking} parameter.
*
* @param factory the thread factory to use
* @param maxThreads the maximum number of allowed threads
* @param blocking {@code true} if the submitter should block when the maximum number of threads has been reached
* @return the executor
* @deprecated Use {@link EnhancedQueueExecutor} instead.
*/
@Deprecated
public static BlockingExecutor threadFactoryExecutor(final ThreadFactory factory, final int maxThreads, final boolean blocking) {
return new ThreadFactoryExecutor(factory, maxThreads, blocking, directExecutor());
}
/**
* Create an executor that executes each task in a new thread. By default up to the given number of threads may run
* concurrently, after which the caller will block or new tasks will be rejected, according to the setting of the
* {@code blocking} parameter.
*
* @param factory the thread factory to use
* @param maxThreads the maximum number of allowed threads
* @param blocking {@code true} if the submitter should block when the maximum number of threads has been reached
* @param taskExecutor the executor which should run each task
* @return the executor
* @deprecated Use {@link EnhancedQueueExecutor} instead.
*/
@Deprecated
public static BlockingExecutor threadFactoryExecutor(final ThreadFactory factory, final int maxThreads, final boolean blocking, final DirectExecutor taskExecutor) {
return new ThreadFactoryExecutor(factory, maxThreads, blocking, taskExecutor);
}
// ==================================================
// REJECTED EXECUTION HANDLERS
// ==================================================
private static final RejectedExecutionHandler ABORT_POLICY = new ThreadPoolExecutor.AbortPolicy();
private static final RejectedExecutionHandler CALLER_RUNS_POLICY = new ThreadPoolExecutor.CallerRunsPolicy();
private static final RejectedExecutionHandler DISCARD_OLDEST_POLICY = new ThreadPoolExecutor.DiscardOldestPolicy();
private static final RejectedExecutionHandler DISCARD_POLICY = new ThreadPoolExecutor.DiscardPolicy();
/**
* Get the abort policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
*
* @return the abort policy
* @see java.util.concurrent.ThreadPoolExecutor.AbortPolicy
*/
public static RejectedExecutionHandler abortPolicy() {
return ABORT_POLICY;
}
/**
* Get the caller-runs policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
*
* @return the caller-runs policy
* @see java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy
*/
public static RejectedExecutionHandler callerRunsPolicy() {
return CALLER_RUNS_POLICY;
}
/**
* Get the discard-oldest policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
*
* @return the discard-oldest policy
* @see java.util.concurrent.ThreadPoolExecutor.DiscardOldestPolicy
*/
public static RejectedExecutionHandler discardOldestPolicy() {
return DISCARD_OLDEST_POLICY;
}
/**
* Get the discard policy for a {@link java.util.concurrent.ThreadPoolExecutor}.
*
* @return the discard policy
* @see java.util.concurrent.ThreadPoolExecutor.DiscardPolicy
*/
public static RejectedExecutionHandler discardPolicy() {
return DISCARD_POLICY;
}
/**
* Get a handoff policy for a {@link java.util.concurrent.ThreadPoolExecutor}. The returned instance will
* delegate to another executor in the event that the task is rejected.
*
* @param target the target executor
* @return the new handoff policy implementation
*/
public static RejectedExecutionHandler handoffPolicy(final Executor target) {
return new HandoffRejectedExecutionHandler(target);
}
// ==================================================
// PROTECTED EXECUTOR SERVICE WRAPPERS
// ==================================================
@Deprecated
public static BlockingExecutor protectedBlockingExecutor(final BlockingExecutor target) {
return new DelegatingBlockingExecutor(target);
}
/**
* Wrap an executor with an {@code ExecutorService} instance which supports all the features of {@code ExecutorService}
* except for shutting down the executor.
*
* @param target the target executor
* @return the executor service
*/
public static ExecutorService protectedExecutorService(final Executor target) {
return new DelegatingExecutorService(target);
}
/**
* Wrap a direct executor with an {@code DirectExecutorService} instance which supports all the features of {@code ExecutorService}
* except for shutting down the executor.
*
* @param target the target executor
* @return the executor service
*/
public static DirectExecutorService protectedDirectExecutorService(final DirectExecutor target) {
return new DelegatingDirectExecutorService(target);
}
/**
* Wrap a scheduled executor with a {@code ScheduledExecutorService} instance which supports all the features of
* {@code ScheduledExecutorService} except for shutting down the executor.
*
* @param target the target executor
* @return the executor service
*/
public static ScheduledExecutorService protectedScheduledExecutorService(final ScheduledExecutorService target) {
return new DelegatingScheduledExecutorService(target);
}
/**
* Wrap a blocking executor with an {@code BlockingExecutorService} instance which supports all the features of
* {@code BlockingExecutorService} except for shutting down the executor.
*
* @param target the target executor
* @return the executor service
*/
@Deprecated
public static BlockingExecutorService protectedBlockingExecutorService(final BlockingExecutor target) {
return new DelegatingBlockingExecutorService(target);
}
// ==================================================
// THREAD FACTORIES
// ==================================================
/**
* Create a thread factory which resets all thread-local storage and delegates to the given thread factory.
* You must have the {@link RuntimePermission}{@code ("modifyThread")} permission to use this method.
*
* @param delegate the delegate thread factory
* @return the resetting thread factory
* @throws SecurityException if the caller does not have the {@link RuntimePermission}{@code ("modifyThread")}
* permission
*/
public static ThreadFactory resettingThreadFactory(final ThreadFactory delegate) throws SecurityException {
return wrappingThreadFactory(resettingExecutor(directExecutor()), delegate);
}
/**
* Creates a thread factory which executes the thread task via the given task wrapping executor.
*
* @param taskWrapper the task wrapping executor
* @param delegate the delegate thread factory
* @return the wrapping thread factory
*/
public static ThreadFactory wrappingThreadFactory(final DirectExecutor taskWrapper, final ThreadFactory delegate) {
return new WrappingThreadFactory(delegate, taskWrapper);
}
private static final Runnable TCCL_RESETTER = new Runnable() {
public void run() {
Thread.currentThread().setContextClassLoader(null);
}
public String toString() {
return "ContextClassLoader-resetting Runnable";
}
};
// ==================================================
// RUNNABLES
// ==================================================
private static final Runnable NULL_RUNNABLE = NullRunnable.getInstance();
private static final Runnable THREAD_LOCAL_RESETTER;
/**
* Get the null runnable which does nothing.
*
* @return the null runnable
*/
public static Runnable nullRunnable() {
return NULL_RUNNABLE;
}
/**
* Get a {@code Runnable} which, when executed, clears the thread-local storage of the calling thread.
* You must have the {@link RuntimePermission}{@code ("modifyThread")}
* permission to use this method.
*
* @return the runnable
* @throws SecurityException if the caller does not have the {@link RuntimePermission}{@code ("modifyThread")}
* permission
*/
public static Runnable threadLocalResetter() throws SecurityException {
checkAccess(MODIFY_THREAD_PERMISSION);
return THREAD_LOCAL_RESETTER;
}
/**
* Get a {@code Runnable} which, when executed, clears the thread context class loader (if the caller has sufficient
* privileges).
*
* @return the runnable
*/
public static Runnable contextClassLoaderResetter() {
return TCCL_RESETTER;
}
/**
* Get a task that runs the given task through the given direct executor.
*
* @param executor the executor to run the task through
* @param task the task to run
* @return an encapsulating task
*/
public static Runnable executorTask(final DirectExecutor executor, final Runnable task) {
return new ExecutorTask(executor, task);
}
/**
* Create a task that is a composite of several other tasks.
*
* @param runnables the tasks
* @return the composite task
*/
public static Runnable compositeTask(final Runnable... runnables) {
return new CompositeTask(runnables.clone());
}
/**
* Create a task that delegates to the given task, preserving the context classloader which was in effect when
* this method was invoked.
*
* @param delegate the delegate runnable
* @return the wrapping runnable
* @throws SecurityException if a security manager exists and the caller does not have the {@code "copyClassLoader"}
* {@link RuntimePermission}.
*/
public static Runnable classLoaderPreservingTask(final Runnable delegate) throws SecurityException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(COPY_CONTEXT_CLASSLOADER_PERMISSION);
}
return classLoaderPreservingTaskUnchecked(delegate);
}
static final ClassLoader SAFE_CL;
static {
ClassLoader safeClassLoader = JBossExecutors.class.getClassLoader();
if (safeClassLoader == null) {
safeClassLoader = ClassLoader.getSystemClassLoader();
}
if (safeClassLoader == null) {
safeClassLoader = new ClassLoader() {
};
}
SAFE_CL = safeClassLoader;
}
static Runnable classLoaderPreservingTaskUnchecked(final Runnable delegate) {
Assert.checkNotNullParam("delegate", delegate);
return new ContextClassLoaderSavingRunnable(getContextClassLoader(Thread.currentThread()), delegate);
}
static final Unsafe unsafe;
static final long contextClassLoaderOffs;
static {
unsafe = AccessController.doPrivileged(new PrivilegedAction
*
*/
private static final int STATE_MAYBE_INTERRUPTED = 0;
/**
* The thread is not interrupted, and interrupts will be deferred. Possible transitions:
*
*
*/
private static final int STATE_INTERRUPT_DEFERRED = 1;
/**
* The thread is not interrupted, but there is an interrupt pending for once deferral is ended. Possible transitions:
*
*
*/
private static final int STATE_INTERRUPT_PENDING = 2;
/**
* The thread is in the process of executing interruption logic. If the thread attempts to defer interrupts
* during this phase, it will block until the interruption logic is complete.
*/
private static final int STATE_INTERRUPT_IN_PROGRESS = 3;
private final AtomicInteger stateRef = new AtomicInteger();
/**
* Construct a new instance.
*
* @param target the runnable target
* @see Thread#Thread(Runnable)
*/
public JBossThread(final Runnable target) {
super(target);
}
/**
* Construct a new instance.
*
* @param target the runnable target
* @param name the initial thread name
* @see Thread#Thread(Runnable, String)
*/
public JBossThread(final Runnable target, final String name) {
super(target, name);
}
/**
* Construct a new instance.
*
* @param group the parent thread group
* @param target the runnable target
* @see Thread#Thread(ThreadGroup, Runnable)
* @throws SecurityException if the current thread cannot create a thread in the specified thread group
*/
public JBossThread(final ThreadGroup group, final Runnable target) throws SecurityException {
super(group, target);
}
/**
* Construct a new instance.
*
* @param group the parent thread group
* @param target the runnable target
* @param name the initial thread name
* @see Thread#Thread(ThreadGroup,Runnable,String)
* @throws SecurityException if the current thread cannot create a thread in the specified thread group
*/
public JBossThread(final ThreadGroup group, final Runnable target, final String name) throws SecurityException {
super(group, target, name);
}
/**
* Construct a new instance.
*
* @param group the parent thread group
* @param target the runnable target
* @param name the initial thread name
* @see Thread#Thread(ThreadGroup,Runnable,String,long)
* @throws SecurityException if the current thread cannot create a thread in the specified thread group
*/
public JBossThread(final ThreadGroup group, final Runnable target, final String name, final long stackSize) throws SecurityException {
super(group, target, name, stackSize);
}
/**
* Interrupt this thread. Logs a trace message and calls the current interrupt handler, if any. The interrupt
* handler is called from the calling thread, not the thread being interrupted.
*/
public void interrupt() {
final boolean differentThread = Thread.currentThread() != this;
if (differentThread) checkAccess();
// fast check
if (isInterrupted()) return;
final AtomicInteger stateRef = this.stateRef;
int oldVal, newVal;
do {
oldVal = stateRef.get();
if (oldVal == STATE_INTERRUPT_PENDING || oldVal == STATE_INTERRUPT_IN_PROGRESS) {
// already set
Messages.msg.tracef("Interrupting thread \"%s\" (already interrupted)", this);
return;
} else if (oldVal == STATE_INTERRUPT_DEFERRED) {
newVal = STATE_INTERRUPT_PENDING;
} else {
newVal = STATE_INTERRUPT_IN_PROGRESS;
}
} while (! stateRef.compareAndSet(oldVal, newVal));
if (newVal == STATE_INTERRUPT_IN_PROGRESS) try {
doInterrupt();
} finally {
// after we return, the thread could be un-interrupted at any time without our knowledge
stateRef.set(STATE_MAYBE_INTERRUPTED);
if (differentThread) {
// unpark the thread if it was waiting to defer interrupts
// interrupting the thread will unpark it; it might park after the interrupt though, or wake up before the state is restored
LockSupport.unpark(this);
}
} else {
Messages.intMsg.tracef("Interrupting thread \"%s\" (deferred)", this);
}
}
private void doInterrupt() {
if (isInterrupted()) return;
Messages.msg.tracef("Interrupting thread \"%s\"", this);
try {
super.interrupt();
} finally {
final InterruptHandler interruptHandler = this.interruptHandler;
if (interruptHandler != null) {
try {
interruptHandler.handleInterrupt(this);
} catch (Throwable t) {
Messages.msg.interruptHandlerThrew(t, interruptHandler);
}
}
}
}
public boolean isInterrupted() {
return this == Thread.currentThread() ? super.isInterrupted() : super.isInterrupted() || (stateRef.get() == STATE_INTERRUPT_PENDING);
}
/**
* Defer interrupts for the duration of some task. Once the task is complete, any deferred interrupt will be
* delivered to the thread, thus the thread interrupt status should be checked upon return. If the current thread
* is not a {@code JBossThread}, the task is simply run as-is.
*
* @param task the task to run
*/
public static void executeWithInterruptDeferred(final Runnable task) {
executeWithInterruptDeferred(JBossExecutors.directExecutor(), task);
}
/**
* Defer interrupts for the duration of some task. Once the task is complete, any deferred interrupt will be
* delivered to the thread, thus the thread interrupt status should be checked upon return. If the current thread
* is not a {@code JBossThread}, the task is simply run as-is.
*
* @param directExecutor the task executor to use
* @param task the task to run
*/
public static void executeWithInterruptDeferred(final DirectExecutor directExecutor, final Runnable task) {
final JBossThread thread = currentThread();
if (registerDeferral(thread)) try {
directExecutor.execute(task);
} finally {
unregisterDeferral(thread);
} else {
// already deferred
directExecutor.execute(task);
}
}
/**
* Defer interrupts for the duration of some task. Once the task is complete, any deferred interrupt will be
* delivered to the thread, thus the thread interrupt status should be checked upon return. If the current thread
* is not a {@code JBossThread}, the task is simply run as-is.
*
* @param action the task to run
* @param
* InterruptHandler oldHandler = JBossThread.getAndSetInterruptHandler(newHandler);
* try {
* ...execute interrupt-sensitive operation...
* } finally {
* JBossThread.getAndSetInterruptHandler(oldHandler);
* }
*
*
* @param newInterruptHandler the new interrupt handler
* @return the old interrupt handler
*/
public static InterruptHandler getAndSetInterruptHandler(final InterruptHandler newInterruptHandler) {
final JBossThread thread = currentThread();
if (thread == null) {
throw Messages.msg.noInterruptHandlers();
}
try {
return thread.interruptHandler;
} finally {
thread.interruptHandler = newInterruptHandler;
}
}
public static (cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public StoppedExecutorException(final Throwable cause) {
super(cause);
}
/**
* Constructs a {@code StoppedExecutorException} with the specified detail message and cause.
*
* @param msg the detail message
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public StoppedExecutorException(final String msg, final Throwable cause) {
super(msg, cause);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/TaskNotifier.java 0000664 0000000 0000000 00000002731 13252743601 0026566 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
/**
* A notifier which is called when tasks start, stop, or fail.
*
* @param (cause == null ? null : cause.toString())
* (which typically contains the class and detail message of {@code cause}).
*
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public ThreadCreationException(final Throwable cause) {
super(cause);
}
/**
* Constructs a {@code ThreadCreationException} with the specified detail message and cause.
*
* @param msg the detail message
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()} method)
*/
public ThreadCreationException(final String msg, final Throwable cause) {
super(msg, cause);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ThreadFactoryExecutor.java 0000664 0000000 0000000 00000023335 13252743601 0030445 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.jboss.threads.management.BoundedThreadPoolExecutorMBean;
import org.wildfly.common.Assert;
@Deprecated
class ThreadFactoryExecutor implements BlockingExecutor, BoundedThreadPoolExecutorMBean {
private final ThreadFactory factory;
private final Semaphore limitSemaphore;
private final DirectExecutor taskExecutor;
private final Object lock = new Object();
private int maxThreads;
private int largestThreadCount;
private int currentThreadCount;
private final AtomicInteger rejected = new AtomicInteger();
private volatile boolean blocking;
ThreadFactoryExecutor(final ThreadFactory factory, int maxThreads, boolean blocking, final DirectExecutor taskExecutor) {
this.factory = factory;
this.maxThreads = maxThreads;
this.blocking = blocking;
this.taskExecutor = taskExecutor;
limitSemaphore = new Semaphore(maxThreads);
}
public int getMaxThreads() {
synchronized (lock) {
return maxThreads;
}
}
public void setMaxThreads(final int maxThreads) {
Assert.checkMinimumParameter("maxThreads", 0, maxThreads);
synchronized (lock) {
final int old = this.maxThreads;
final int diff = old - maxThreads;
if (diff < 0) {
limitSemaphore.release(-diff);
} else if (diff > 0) {
if (! limitSemaphore.tryAcquire(diff)) {
throw Messages.msg.cannotReduceMaxBelowCurrent();
}
}
this.maxThreads = maxThreads;
}
}
public void execute(final Runnable task) {
Assert.checkNotNullParam("task", task);
try {
final Semaphore semaphore = limitSemaphore;
if (blocking) {
try {
semaphore.acquire();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw Messages.msg.executionInterrupted();
}
} else {
if (! semaphore.tryAcquire()) {
throw Messages.msg.taskLimitReached();
}
}
boolean ok = false;
try {
final Thread thread = factory.newThread(new Runnable() {
public void run() {
try {
synchronized (lock) {
int t = ++currentThreadCount;
if (t > largestThreadCount) {
largestThreadCount = t;
}
}
taskExecutor.execute(task);
synchronized (lock) {
currentThreadCount--;
}
} finally {
limitSemaphore.release();
}
}
});
if (thread == null) {
throw Messages.msg.noThreadCreated();
}
thread.start();
ok = true;
} finally {
if (! ok) semaphore.release();
}
} catch (RejectedExecutionException e) {
rejected.getAndIncrement();
throw e;
}
}
public void executeBlocking(final Runnable task) throws RejectedExecutionException, InterruptedException {
Assert.checkNotNullParam("task", task);
try {
final Semaphore semaphore = limitSemaphore;
semaphore.acquire();
boolean ok = false;
try {
final Thread thread = factory.newThread(new Runnable() {
public void run() {
try {
synchronized (lock) {
int t = ++currentThreadCount;
if (t > largestThreadCount) {
largestThreadCount = t;
}
}
taskExecutor.execute(task);
synchronized (lock) {
currentThreadCount--;
}
} finally {
limitSemaphore.release();
}
}
});
if (thread == null) {
throw Messages.msg.noThreadCreated();
}
thread.start();
ok = true;
} finally {
if (! ok) semaphore.release();
}
} catch (RejectedExecutionException e) {
rejected.getAndIncrement();
throw e;
}
}
public void executeBlocking(final Runnable task, final long timeout, final TimeUnit unit) throws RejectedExecutionException, InterruptedException {
Assert.checkNotNullParam("task", task);
try {
final Semaphore semaphore = limitSemaphore;
if (! semaphore.tryAcquire(timeout, unit)) {
throw Messages.msg.executionTimedOut();
}
boolean ok = false;
try {
final Thread thread = factory.newThread(new Runnable() {
public void run() {
try {
synchronized (lock) {
int t = ++currentThreadCount;
if (t > largestThreadCount) {
largestThreadCount = t;
}
}
taskExecutor.execute(task);
synchronized (lock) {
currentThreadCount--;
}
} finally {
limitSemaphore.release();
}
}
});
if (thread == null) {
throw Messages.msg.noThreadCreated();
}
thread.start();
ok = true;
} finally {
if (! ok) semaphore.release();
}
} catch (RejectedExecutionException e) {
rejected.getAndIncrement();
throw e;
}
}
public void executeNonBlocking(final Runnable task) throws RejectedExecutionException {
Assert.checkNotNullParam("task", task);
try {
final Semaphore semaphore = limitSemaphore;
if (! semaphore.tryAcquire()) {
throw Messages.msg.taskLimitReached();
}
boolean ok = false;
try {
final Thread thread = factory.newThread(new Runnable() {
public void run() {
try {
synchronized (lock) {
int t = ++currentThreadCount;
if (t > largestThreadCount) {
largestThreadCount = t;
}
}
taskExecutor.execute(task);
synchronized (lock) {
currentThreadCount--;
}
} finally {
limitSemaphore.release();
}
}
});
if (thread == null) {
throw Messages.msg.noThreadCreated();
}
thread.start();
ok = true;
} finally {
if (! ok) semaphore.release();
}
} catch (RejectedExecutionException e) {
rejected.getAndIncrement();
throw e;
}
}
public boolean isBlocking() {
return blocking;
}
public void setBlocking(final boolean blocking) {
this.blocking = blocking;
}
public int getLargestThreadCount() {
synchronized (lock) {
return largestThreadCount;
}
}
public int getCurrentThreadCount() {
synchronized (lock) {
return currentThreadCount;
}
}
/** {@inheritDoc} */
public int getQueueSize() {
return 0;
}
public int getRejectedCount() {
return rejected.get();
}
public long getKeepAliveTime() {
return 0L;
}
public void setKeepAliveTime(final long milliseconds) {
if (milliseconds != 0L) {
throw Messages.msg.keepAliveNotZero();
}
}
public String toString() {
return String.format("%s (%s)", super.toString(), factory);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ThreadFormattedNameExecutor.java 0000664 0000000 0000000 00000002776 13252743601 0031572 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
class ThreadFormattedNameExecutor implements DirectExecutor {
private final String nameFormat;
private final DirectExecutor delegate;
ThreadFormattedNameExecutor(final String nameFormat, final DirectExecutor delegate) {
this.nameFormat = nameFormat;
this.delegate = delegate;
}
public void execute(final Runnable command) {
final JBossThread thr = JBossThread.currentThread();
final String oldName = thr.getName();
thr.setName(thr.getThreadNameInfo().format(thr, nameFormat));
try {
delegate.execute(command);
} finally {
thr.setName(oldName);
}
}
public String toString() {
return String.format("%s format=\"%s\" -> %s", super.toString(), nameFormat, delegate);
}
} jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ThreadLocalResetter.java 0000664 0000000 0000000 00000004113 13252743601 0030060 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.lang.reflect.Field;
import java.security.AccessController;
final class ThreadLocalResetter implements Runnable {
private static final ThreadLocalResetter INSTANCE = new ThreadLocalResetter();
private static final long threadLocalMapOffs;
private static final long inheritableThreadLocalMapOffs;
static {
final Field threadLocals = AccessController.doPrivileged(new DeclaredFieldAction(Thread.class, "threadLocals"));
threadLocalMapOffs = threadLocals == null ? 0 : JBossExecutors.unsafe.objectFieldOffset(threadLocals);
final Field inheritableThreadLocals = AccessController.doPrivileged(new DeclaredFieldAction(Thread.class, "inheritableThreadLocals"));
inheritableThreadLocalMapOffs = inheritableThreadLocals == null ? 0 : JBossExecutors.unsafe.objectFieldOffset(inheritableThreadLocals);
}
static ThreadLocalResetter getInstance() {
return INSTANCE;
}
private ThreadLocalResetter() {
}
public void run() {
final Thread thread = Thread.currentThread();
if (threadLocalMapOffs != 0) JBossExecutors.unsafe.putObject(thread, threadLocalMapOffs, null);
if (inheritableThreadLocalMapOffs != 0) JBossExecutors.unsafe.putObject(thread, inheritableThreadLocalMapOffs, null);
}
public String toString() {
return "Thread-local resetting Runnable";
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ThreadNameExecutor.java 0000664 0000000 0000000 00000002652 13252743601 0027715 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
class ThreadNameExecutor implements DirectExecutor {
private final String newName;
private final DirectExecutor delegate;
ThreadNameExecutor(final String newName, final DirectExecutor delegate) {
this.newName = newName;
this.delegate = delegate;
}
public void execute(final Runnable command) {
final Thread thr = Thread.currentThread();
final String oldName = thr.getName();
thr.setName(newName);
try {
delegate.execute(command);
} finally {
thr.setName(oldName);
}
}
public String toString() {
return String.format("%s name=\"%s\" -> %s", super.toString(), newName, delegate);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ThreadNameInfo.java 0000664 0000000 0000000 00000007217 13252743601 0027014 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
/**
* Thread name information.
*/
final class ThreadNameInfo {
private final long globalThreadSequenceNum;
private final long perFactoryThreadSequenceNum;
private final long factorySequenceNum;
ThreadNameInfo(final long globalThreadSequenceNum, final long perFactoryThreadSequenceNum, final long factorySequenceNum) {
this.globalThreadSequenceNum = globalThreadSequenceNum;
this.perFactoryThreadSequenceNum = perFactoryThreadSequenceNum;
this.factorySequenceNum = factorySequenceNum;
}
public long getGlobalThreadSequenceNum() {
return globalThreadSequenceNum;
}
public long getPerFactoryThreadSequenceNum() {
return perFactoryThreadSequenceNum;
}
public long getFactorySequenceNum() {
return factorySequenceNum;
}
private static final Pattern searchPattern = Pattern.compile("([^%]+)|%.");
/**
* Format the thread name string.
*
*
*
* @param thread the thread
* @param formatString the format string
* @return the thread name string
*/
public String format(Thread thread, String formatString) {
final StringBuilder builder = new StringBuilder(formatString.length() * 5);
final ThreadGroup group = thread.getThreadGroup();
final Matcher matcher = searchPattern.matcher(formatString);
while (matcher.find()) {
if (matcher.group(1) != null) {
builder.append(matcher.group());
} else {
switch (matcher.group().charAt(1)) {
case '%': builder.append('%'); break;
case 't': builder.append(perFactoryThreadSequenceNum); break;
case 'g': builder.append(globalThreadSequenceNum); break;
case 'f': builder.append(factorySequenceNum); break;
case 'p': if (group != null) appendGroupPath(group, builder); break;
case 'i': builder.append(thread.getId());
case 'G': if (group != null) builder.append(group.getName()); break;
}
}
}
return builder.toString();
}
private static void appendGroupPath(ThreadGroup group, StringBuilder builder) {
final ThreadGroup parent = group.getParent();
if (parent != null) {
appendGroupPath(parent, builder);
builder.append(':');
}
builder.append(group.getName());
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/ThreadNameNotatingExecutor.java 0000664 0000000 0000000 00000002754 13252743601 0031424 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
class ThreadNameNotatingExecutor implements DirectExecutor {
private final String notation;
private final DirectExecutor delegate;
ThreadNameNotatingExecutor(final String notation, final DirectExecutor delegate) {
this.notation = notation;
this.delegate = delegate;
}
public void execute(final Runnable command) {
final Thread thr = Thread.currentThread();
final String oldName;
oldName = thr.getName();
thr.setName(oldName + " (" + notation + ')');
try {
delegate.execute(command);
} finally {
thr.setName(oldName);
}
}
public String toString() {
return String.format("%s notation=\"%s\" -> %s", super.toString(), notation, delegate);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/UninterruptibleExecutor.java 0000664 0000000 0000000 00000002076 13252743601 0031100 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.concurrent.Executor;
class UninterruptibleExecutor implements Executor {
private final Executor delegate;
UninterruptibleExecutor(final Executor delegate) {
this.delegate = delegate;
}
public void execute(final Runnable command) {
JBossExecutors.executeUninterruptibly(delegate, command);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/Version.java 0000664 0000000 0000000 00000004623 13252743601 0025613 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
/**
*
*/
public final class Version {
private Version() {
}
private static final String JAR_NAME;
private static final String VERSION_STRING;
static {
Properties versionProps = new Properties();
String jarName = "(unknown)";
String versionString = "(unknown)";
try (InputStream stream = Version.class.getResourceAsStream("Version.properties")) {
if (stream != null) try (InputStreamReader reader = new InputStreamReader(stream, StandardCharsets.UTF_8)) {
versionProps.load(reader);
jarName = versionProps.getProperty("jarName", jarName);
versionString = versionProps.getProperty("version", versionString);
}
} catch (IOException ignored) {
}
JAR_NAME = jarName;
VERSION_STRING = versionString;
try {
Messages.msg.version(versionString);
} catch (Throwable ignored) {}
}
/**
* Get the name of the JBoss Modules JAR.
*
* @return the name
*/
public static String getJarName() {
return JAR_NAME;
}
/**
* Get the version string of JBoss Modules.
*
* @return the version string
*/
public static String getVersionString() {
return VERSION_STRING;
}
/**
* Print out the current version on {@code System.out}.
*
* @param args ignored
*/
public static void main(String[] args) {
System.out.printf("JBoss Threads version %s\n", VERSION_STRING);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/Version.properties 0000664 0000000 0000000 00000001353 13252743601 0027063 0 ustar 00root root 0000000 0000000 #
# JBoss, Home of Professional Open Source.
# Copyright 2017 Red Hat, Inc., and individual contributors
# as indicated by the @author tags.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
version=${project.version}
jarName=${project.artifactId}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/WrappingExecutor.java 0000664 0000000 0000000 00000003045 13252743601 0027471 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.Executor;
/**
* An executor which runs a task within the given direct executor.
*/
public interface WrappingExecutor extends Executor {
/**
* Run the given task directly, without a wrapper.
*
* @param task the task to run
* @throws RejectedExecutionException if the execution was rejected for some reason
*/
void execute(Runnable task) throws RejectedExecutionException;
/**
* Run the given task within the given wrapper.
*
* @param directExecutor the task wrapper
* @param task the task to run
* @throws RejectedExecutionException if the execution was rejected for some reason
*/
void execute(DirectExecutor directExecutor, Runnable task) throws RejectedExecutionException;
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/WrappingThreadFactory.java 0000664 0000000 0000000 00000002520 13252743601 0030427 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads;
import java.util.concurrent.ThreadFactory;
class WrappingThreadFactory implements ThreadFactory {
private final ThreadFactory delegate;
private final DirectExecutor taskWrapper;
WrappingThreadFactory(final ThreadFactory delegate, final DirectExecutor taskWrapper) {
this.delegate = delegate;
this.taskWrapper = taskWrapper;
}
public Thread newThread(final Runnable r) {
return delegate.newThread(JBossExecutors.executorTask(taskWrapper, r));
}
public String toString() {
return String.format("%s (%s) -> %s", super.toString(), taskWrapper, delegate);
}
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management/ 0000775 0000000 0000000 00000000000 13252743601 0025432 5 ustar 00root root 0000000 0000000 BoundedQueueThreadPoolExecutorMBean.java 0000664 0000000 0000000 00000002000 13252743601 0035177 0 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads.management;
/**
*
*/
@Deprecated
public interface BoundedQueueThreadPoolExecutorMBean extends BoundedThreadPoolExecutorMBean {
boolean isAllowCoreThreadTimeout();
void setAllowCoreThreadTimeout(boolean allow);
int getCoreThreads();
void setCoreThreads(int newSize);
}
BoundedThreadPoolExecutorMBean.java 0000664 0000000 0000000 00000001633 13252743601 0034205 0 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads.management;
/**
*
*/
@Deprecated
public interface BoundedThreadPoolExecutorMBean extends ThreadPoolExecutorMBean {
boolean isBlocking();
void setBlocking(boolean blocking);
}
ManageableThreadPoolExecutorService.java 0000664 0000000 0000000 00000002540 13252743601 0035255 0 ustar 00root root 0000000 0000000 jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads.management;
import java.util.concurrent.ExecutorService;
import org.wildfly.common.annotation.NotNull;
/**
* A thread pool for which an MBean can be obtained.
*/
public interface ManageableThreadPoolExecutorService extends ExecutorService {
/**
* Create or acquire an MXBean instance for this thread pool. Note that the thread pool itself will not
* do anything in particular to register (or unregister) the MXBean with a JMX server; that is the caller's
* responsibility.
*
* @return the MXBean instance (must not be {@code null})
*/
@NotNull
StandardThreadPoolMXBean getThreadPoolMXBean();
}
jboss-threads-2.3.2.Final/src/main/java/org/jboss/threads/management/StandardThreadPoolMXBean.java 0000664 0000000 0000000 00000024164 13252743601 0033061 0 ustar 00root root 0000000 0000000 /*
* JBoss, Home of Professional Open Source.
* Copyright 2017 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.threads.management;
/**
* An MXBean which contains the attributes and operations found on all standard thread pools.
*/
public interface StandardThreadPoolMXBean {
/**
* Get the pool size growth resistance factor. If the thread pool does not support growth resistance,
* then {@code 0.0} (no resistance) is returned.
*
* @return the growth resistance factor ({@code 0.0 ≤ n ≤ 1.0})
*/
float getGrowthResistance();
/**
* Set the pool size growth resistance factor, if supported.
*
* @param value the growth resistance factor ({@code 0.0 ≤ n ≤ 1.0})
*/
void setGrowthResistance(float value);
/**
* Determine whether the thread pool supports a growth resistance factor.
*
* @return {@code true} if the growth resistance factor is supported, {@code false} otherwise
*/
boolean isGrowthResistanceSupported();
/**
* Get the core pool size. This is the size below which new threads will always be created if no idle threads
* are available. If the thread pool does not support a separate core pool size, this size will match the
* maximum size.
*
* @return the core pool size
*/
int getCorePoolSize();
/**
* Set the core pool size. If the configured maximum pool size is less than the configured core size, the
* core size will be reduced to match the maximum size when the thread pool is constructed. If the thread pool
* does not support a separate core pool size, this setting will be ignored.
*
* @param corePoolSize the core pool size (must be greater than or equal to 0)
*/
void setCorePoolSize(int corePoolSize);
/**
* Determine whether this implementation supports a separate core pool size.
*
* @return {@code true} if a separate core size is supported; {@code false} otherwise
*/
boolean isCorePoolSizeSupported();
/**
* Attempt to start a core thread without submitting work to it.
*
* @return {@code true} if the thread was started, or {@code false} if the pool is filled to the core size, the
* thread could not be created, or prestart of core threads is not supported.
*/
boolean prestartCoreThread();
/**
* Attempt to start all core threads. This is usually equivalent to calling {@link #prestartCoreThread()} in a loop
* until it returns {@code false} and counting the {@code true} results.
*
* @return the number of started core threads (may be 0)
*/
int prestartAllCoreThreads();
/**
* Determine whether this thread pool allows manual pre-start of core threads.
*
* @return {@code true} if pre-starting core threads is supported, {@code false} otherwise
*/
boolean isCoreThreadPrestartSupported();
/**
* Get the maximum pool size. This is the absolute upper limit to the size of the thread pool.
*
* @return the maximum pool size
*/
int getMaximumPoolSize();
/**
* Set the maximum pool size. If the configured maximum pool size is less than the configured core size, the
* core size will be reduced to match the maximum size when the thread pool is constructed.
*
* @param maxPoolSize the maximum pool size (must be greater than or equal to 0)
*/
void setMaximumPoolSize(final int maxPoolSize);
/**
* Get an estimate of the current number of active threads in the pool.
*
* @return an estimate of the current number of active threads in the pool
*/
int getPoolSize();
/**
* Get an estimate of the peak number of threads that the pool has ever held.
*
* @return an estimate of the peak number of threads that the pool has ever held
*/
int getLargestPoolSize();
/**
* Get an estimate of the current number of active (busy) threads.
*
* @return an estimate of the active count
*/
int getActiveCount();
/**
* Determine whether core threads are allowed to time out. A "core thread" is defined as any thread in the pool
* when the pool size is below the pool's {@linkplain #getCorePoolSize() core pool size}. If the thread pool
* does not support a separate core pool size, this method should return {@code false}.
*