/*
* Copyright (c) 2008-2013 EMC Corporation
* All Rights Reserved
*/
package com.emc.storageos.services.util;
import java.util.concurrent.Callable;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.RunnableScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
/**
* Customized ScheduledThreadPoolExecutor that provides: - Name prefix for all
* threads in the pool via @NamedThreadFactory - A Embedded @NamedThreadFactory
* that creates threads with prefix
*
* @author luoq1
*
*/
public class NamedScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
// append running task name to the executing thread name?
private boolean appendTaskName = false;
// the name prefix for the threads in the pool
private String poolName;
/**
* Creates a ScheduledThreadPoolExecutor with fixed poolName size and a
* prefix for thread name.
*
* @param poolName
* - the name prefix for any threads in the poolName
* @param fixedPoolSize
* - the number of threads to keep in the pool.
*/
public NamedScheduledThreadPoolExecutor(String poolName, int fixPoolSize) {
super(fixPoolSize, new NamedThreadFactory(poolName));
setPoolName(poolName);
}
/**
* Creates a ScheduledThreadPoolExecutor with fixed poolName size and a
* prefix for thread name.
*
* @param poolName
* - the name prefix for any threads in the poolName
* @param fixPoolSize
* - the number of threads to keep in the pool.
* @param handler
* - the handler to use when execution is blocked because the
* thread bounds and queue capacities are reached
*/
public NamedScheduledThreadPoolExecutor(String poolName, int fixPoolSize,
RejectedExecutionHandler handler) {
super(fixPoolSize, new NamedThreadFactory(poolName), handler);
setPoolName(poolName);
}
/**
* Creates a ScheduledThreadPoolExecutor with fixed poolName size and a
* prefix for thread name.
*
* @param poolName
* - the name prefix for any threads in the poolName
* @param fixPoolSize
* - the number of threads to keep in the pool.
* @param threadFactory
* - thread factory user gave will be wrapped into a @NamedThreadFactory
*/
public NamedScheduledThreadPoolExecutor(String poolName, int fixPoolSize,
ThreadFactory threadFactory) {
super(fixPoolSize, new NamedThreadFactory(poolName, threadFactory));
setPoolName(poolName);
}
/**
* Creates a ScheduledThreadPoolExecutor with fixed poolName size and a
* prefix for thread name.
*
* @param poolName
* - the name prefix for any threads in the poolName
* @param fixPoolSize
* - the number of threads to keep in the pool.
* @param threadFactory
* - thread factory user gave will be wrapped into a @NamedThreadFactory
* @param handler
* - the handler to use when execution is blocked because the
* thread bounds and queue capacities are reached
*/
public NamedScheduledThreadPoolExecutor(String poolName, int fixPoolSize,
ThreadFactory threadFactory, RejectedExecutionHandler handler) {
super(fixPoolSize, new NamedThreadFactory(poolName, threadFactory), handler);
setPoolName(poolName);
}
// ------Methods ----------------------------------
// -------------------------------------------------
// beforeExecute() Append running task name
// afterExecute() Reset thead name after task
// -------------------------------------------------
/**
* Wrap the running task within @NamedTask so that we can easily capture
* its name. The default decorateTask method from super class @ScheduledThreadPoolExecutor
* hides every runnable within its own wrapped class -
*
* @RunnableScheduledFuture.
*/
@Override
protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r,
RunnableScheduledFuture<V> task) {
return new NamedScheduledTask<V>(r.getClass().getSimpleName(), task);
}
/**
* See comments for above method.
*/
@Override
protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c,
RunnableScheduledFuture<V> task) {
return new NamedScheduledTask<V>(c.getClass().getSimpleName(), task);
}
/**
* Changes executing thread name to append the task name if appendTaskName
* is set to true.
*/
@Override
protected void beforeExecute(Thread t, Runnable r) {
if (isAppendTaskName()) {
NamedThreadPoolHelper.changeNameBeforeExecute(t, r);
}
super.beforeExecute(t, r);
}
/**
* Resets the thread name back to default thread pool name(prefix).
*/
@Override
protected void afterExecute(Runnable r, Throwable t) {
if (isAppendTaskName()) {
NamedThreadPoolHelper.resetNameAfterExecute(r, t);
}
super.afterExecute(r, t);
}
/**
* Checks if the appendTaskName flag is set.
*
* @return - true/false
*/
public boolean isAppendTaskName() {
return appendTaskName;
}
/**
* Sets the appendTaskName flag, true to append the task name to running
* thread's name.
*
* @param appendTaskName
*/
public void setAppendTaskName(boolean appendTaskName) {
this.appendTaskName = appendTaskName;
}
/**
* Finds the prefix name.
*
* @return
*/
public String getPoolName() {
return poolName;
}
/**
* Sets the prefix name.
*
* @param poolName
*/
private void setPoolName(String poolName) {
this.poolName = poolName;
}
}