package org.zstack.core.thread; import org.apache.logging.log4j.ThreadContext; import org.zstack.utils.logging.CLogger; import org.zstack.utils.logging.CLoggerImpl; import java.util.ArrayList; import java.util.List; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; public class ScheduledThreadPoolExecutorExt extends ScheduledThreadPoolExecutor { private static final CLogger _logger =CLoggerImpl.getLogger(ScheduledThreadPoolExecutorExt.class); List<ThreadAroundHook> _hooks = new ArrayList<ThreadAroundHook>(8); public ScheduledThreadPoolExecutorExt(int corePoolSize, ThreadFactory threadFactory, RejectedExecutionHandler handler) { super(corePoolSize, threadFactory, handler); this.setMaximumPoolSize(corePoolSize); } public void registerHook(ThreadAroundHook hook) { synchronized (_hooks) { _hooks.add(hook); } } public void unregisterHook(ThreadAroundHook hook) { synchronized (_hooks) { _hooks.remove(hook); } } @Override protected void beforeExecute(Thread t, Runnable r) { ThreadContext.clearMap(); ThreadContext.clearStack(); ThreadAroundHook debugHook = null; List<ThreadAroundHook> tmpHooks; synchronized (_hooks) { tmpHooks = new ArrayList<ThreadAroundHook>(_hooks); } for (ThreadAroundHook hook : tmpHooks) { debugHook = hook; try { hook.beforeExecute(t, r); } catch (Exception e) { _logger.warn("Unhandle exception happend during executing ThreadAroundHook: " + debugHook.getClass().getCanonicalName(), e); } } } @Override protected void afterExecute(Runnable r, Throwable t) { ThreadContext.clearMap(); ThreadContext.clearStack(); ThreadAroundHook debugHook = null; List<ThreadAroundHook> tmpHooks; synchronized (_hooks) { tmpHooks = new ArrayList<ThreadAroundHook>(_hooks); } for (ThreadAroundHook hook : tmpHooks) { debugHook = hook; try { hook.afterExecute(r, t); } catch (Exception e) { _logger.warn("Unhandle exception happend during executing ThreadAroundHook: " + debugHook.getClass().getCanonicalName(), e); } } } }