org.wisdom.api.concurrent.ManagedExecutorService Maven / Gradle / Ivy
/*
* #%L
* Wisdom-Framework
* %%
* Copyright (C) 2013 - 2015 Wisdom Framework
* %%
* 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.
* #L%
*/
package org.wisdom.api.concurrent;
import com.google.common.util.concurrent.ListeningExecutorService;
import java.util.Collection;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
/**
* Executor Service exposed as a service to execute tasks. This interface
* extends {@link com.google.common.util.concurrent.ListeningExecutorService}
* to make the returned {@link java.util.concurrent.Future} listenable.
*
* The type of thread managed by the thread pool is configured with
* {@link org.wisdom.api.concurrent.ManagedExecutorService.ThreadType}. It configures
* the {@link java.util.concurrent.ThreadFactory} used by the executor.
*
* Unlike regular {@link java.util.concurrent.ExecutorService}, this executor
* returns {@link org.wisdom.api.concurrent.ManagedFutureTask} instead of raw
* {@link java.util.concurrent.Future}.
*/
public interface ManagedExecutorService extends ListeningExecutorService {
/**
* A special name used by the core Wisdom System Executor.
*/
String SYSTEM = "wisdom-system-executor";
/**
* The type of thread to use
*/
enum ThreadType {
POOLED,
DAEMON
}
/**
* @return the name of the thread pool.
*/
public String name();
/**
* Gets the set of task considered as stuck.
*
* @return the set of task that have hung, empty is none.
*/
public Collection getHungTasks();
/**
* Submits a task.
*
* @param task the task
* @return a {@code ManagedFutureTask} representing pending completion of
* the task
* @throws RejectedExecutionException when the pool cannot accept the task.
*/
@Override
ManagedFutureTask submit(Callable task)
throws RejectedExecutionException;
/**
* Submits a task.
*
* @param task the task
* @return a {@code ManagedFutureTask} representing pending completion of
* the task
* @throws RejectedExecutionException when the pool cannot accept the task.
*/
@Override
ManagedFutureTask submit(Runnable task)
throws RejectedExecutionException;
/**
* Submits a task. Submission may throws a {@link RejectedExecutionException} is the underlying executor is not
* able to accept the task.
*
* @param task the task
* @param result the result to return on task completion
* @return a {@code ManagedFutureTask} representing pending completion of
* the task
*/
@Override
ManagedFutureTask submit(Runnable task, T result);
/**
* @return the approximate number of threads that are actively executing tasks.
*/
public int getActiveCount();
/**
* @return the approximate total number of tasks that have completed execution.
*/
public long getCompletedTaskCount();
/**
* @return the core number of threads.
*/
public int getCorePoolSize();
/**
* Returns the thread keep-alive time, which is the amount of time that threads in excess of the core pool size may
* remain idle before being terminated.
*
* @param unit the time unit
* @return the thread keep alive time translated to the given time unit
*/
public long getKeepAliveTime(TimeUnit unit);
/**
* @return the largest number of threads that have ever simultaneously been in the pool.
*/
public int getLargestPoolSize();
/**
* @return the maximum allowed number of threads.
*/
public int getMaximumPoolSize();
/**
* @return the current number of threads in the pool.
*/
public int getPoolSize();
/**
* @return the task queue used by this executor.
*/
public BlockingQueue getQueue();
/**
* Tries to remove from the work queue all {@link java.util.concurrent.Future}
* tasks that have been cancelled. This method can be useful as a
* storage reclamation operation, that has no other impact on
* functionality. Cancelled tasks are never executed, but may
* accumulate in work queues until worker threads can actively
* remove them. Invoking this method instead tries to remove them now.
* However, this method may fail to remove tasks in
* the presence of interference by other threads.
*/
public void purge();
/**
* Removes this task from the executor's internal queue if it is
* present, thus causing it not to be run if it has not already
* started.
*
*
This method may be useful as one part of a cancellation
* scheme. It may fail to remove tasks that have been converted
* into other forms before being placed on the internal queue. For
* example, a task entered using {@code submit} might be
* converted into a form that maintains {@code Future} status.
* However, in such cases, method {@link #purge} may be used to
* remove those Futures that have been cancelled.
*
* @param task the task to remove
* @return {@code true} if the task was removed
*/
public boolean remove(Runnable task);
/**
* @return the approximate total number of tasks that have ever been scheduled for execution.
*/
public long getTaskCount();
/**
* @return the execution statistics.
*/
public ExecutionStatistics getExecutionTimeStatistics();
/**
* Represents execution statistics of a thread pool.
*/
public static class ExecutionStatistics {
private long count;
private long sum;
private long min = Long.MAX_VALUE;
private long max = Long.MIN_VALUE;
/**
* Records a new {@code int} value into the statistics.
*
* @param value the input value
*/
public void accept(int value) {
accept((long) value);
}
/**
* Records a new {@code long} value into the statistics.
*
* @param value the input value
*/
public synchronized void accept(long value) {
++count;
sum += value;
min = Math.min(min, value);
max = Math.max(max, value);
}
/**
* Combines the state of another {@code ExecutionStatistics} into this
* one.
*
* @param other another {@code ExecutionStatistics}
* @throws NullPointerException if {@code other} is null
*/
public synchronized void combine(final ExecutionStatistics other) {
count += other.getCount();
sum += other.getTotalExecutionTime();
min = Math.min(min, other.getMinimumExecutionTime());
max = Math.max(max, other.getMaximumExecutionTime());
}
/**
* Returns a copy of the current statistics.
*
* @return the copied object
*/
public synchronized ExecutionStatistics copy() {
ExecutionStatistics statistics = new ExecutionStatistics();
statistics.combine(this);
return statistics;
}
/**
* Returns the count of values recorded.
*
* @return the count of values
*/
public final synchronized long getCount() {
return count;
}
/**
* Returns the number of tasks that have been recorded.
*
* @return the number of tasks
*/
public final synchronized long getNumberOfTasks() {
return getCount();
}
/**
* Returns the sum of values recorded, or zero if no values have been
* recorded.
*
* @return the sum of values, or zero if none
*/
public final synchronized long getTotalExecutionTime() {
return sum;
}
/**
* Returns the minimum value recorded, or {@code Long.MAX_VALUE} if no
* values have been recorded.
*
* @return the minimum value, or {@code Long.MAX_VALUE} if none
*/
public final synchronized long getMinimumExecutionTime() {
return min;
}
/**
* Returns the maximum value recorded, or {@code Long.MIN_VALUE} if no
* values have been recorded
*
* @return the maximum value, or {@code Long.MIN_VALUE} if none
*/
public final synchronized long getMaximumExecutionTime() {
return max;
}
/**
* Returns the arithmetic mean of values recorded, or zero if no values have been
* recorded.
*
* @return The arithmetic mean of values, or zero if none
*/
public final synchronized double getAverageExecutionTime() {
return getCount() > 0 ? (double) getTotalExecutionTime() / getNumberOfTasks() : 0.0d;
}
@Override
/**
* {@inheritDoc}
*
* Returns a non-empty string representation of this object suitable for
* debugging. The exact presentation format is unspecified and may vary
* between implementations and versions.
*/
public synchronized String toString() {
return String.format(
"%s{count=%d, sum=%d, min=%d, average=%f, max=%d}",
this.getClass().getSimpleName(),
getCount(),
getTotalExecutionTime(),
getMinimumExecutionTime(),
getAverageExecutionTime(),
getMaximumExecutionTime());
}
}
}