版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sir_jun/article/details/37968695
/*
* @(#)TaskExecutor.java 1.0 2004-10-12
*
* Copyright 2005 UFIDA Software Co. Ltd. All rights reserved.
* UFIDA PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package nc.bs.uap.scheduler.impl;
import nc.bs.framework.common.IAttributeManager;
import nc.bs.framework.common.NCLocator;
import nc.bs.framework.component.RemoteProcessComponetFactory;
import nc.bs.framework.execute.Executor;
import nc.bs.framework.task.ICRController;
import nc.bs.framework.tx.NoSpecified;
import nc.bs.logging.Logger;
import nc.bs.uap.scheduler.ITask;
import nc.bs.uap.scheduler.Messages;
import nc.itf.uap.scheduler.IExecutorService;
import nc.vo.uap.scheduler.TaskStatus;
import nc.vo.uap.scheduler.TaskWrapper;
/**
* 任务的执行器。对经过调度的任务进行处理和执行。由任务执行器池生成。
* <p>
* 在接到任务后首先开始执行任务,执行完毕后,把自己加入到任务执行器池的空闲线程队列;自身进入等待状态,等待任务执行器池唤醒。
* 如果没有任务,则进入IDLE的等待状态,如果超时还没有分配的任务,则将通知任务执行器池。任务执行器池根据设定的规则处理此任务执行器。
*
* @author yanglei
* @author hgy 5.3
* @since 3.0
*/
public class TaskExecutor extends Executor {
private volatile TaskWrapper taskWrapper = null;
/* 任务执行器所归属的线程池 */
private TaskExecutorPool pool = null;
private RemoteProcessComponetFactory factory;
private IAttributeManager requestAttrMgr;
private final ICRController crController;
private static boolean SCHEDULE_TEST = "test".equals(System
.getProperty("nc.scheduler.mode"));
/**
* 构造任务执行器
*
* @param name
* 任务执行器的名称。
* @param pool
* 任务执行器所归属的线程池。
*/
TaskExecutor(String name, TaskExecutorPool pool) {
super(name);
this.pool = pool;
crController = NCLocator.getInstance().lookup(ICRController.class);
}
/**
* 执行器运行的主过程。
*/
@Override
public void run() {
for (;;) {
manageNullTask();
if (getTaskWrapper() == null) {
if (pool.notifyTimeOut(this))
return;
else {
continue;
}
} else {
try {
executeTask();
} finally {
TaskWrapper tw = getTaskWrapper();
setTaskWrapper(null);
if (pool.notifyFree(this, tw))
return;
}
}
}
}
/**
* 执行任务。
*/
private void executeTask() {
boolean hasException = false;
TaskWrapper tw = getTaskWrapper();
// Add By 门志永@云达/新华书店项目2013-4-21 START 执行特定的后台任务
/**
* XHFX物流接口_分书同步
* XHFX物流接口_运单同步
*/
if(tw.getTask().getType().equals("1")&&!tw.getTask().getName().equals("XHFX物流接口_运单333同步"))//同步BD_INVBASDOC_PKINVTEMP品种到中间库
return;
tw.setStatus(TaskStatus.RUNNING);
logBeginExecute(tw);
ITask task = tw.getTask();
try {
Logger.init(Messages.LOGGER_ID);
long now = System.currentTimeMillis();
TaskWrapper.taskWrapperContext.set(tw);
bgProcess(tw, true, null);
tw.setThread(Thread.currentThread());
if (SCHEDULE_TEST
|| task.getTaskBody().getClass().getAnnotation(
NoSpecified.class) != null) {
Messages.log.debug("execute task without default transaction: " + task.getTaskBody());
task.getTaskBody().execute();
} else {
IExecutorService es = (IExecutorService) NCLocator
.getInstance().lookup(IExecutorService.class.getName());
es.executeTask_RequiresNew(task.getTaskBody());
}
tw.setStatus(TaskStatus.FINISHED);
logExecuteFinished(tw, System.currentTimeMillis() - now);
} catch (Exception e) {
tw.setStatus(TaskStatus.FAILED);
executeTaskException(tw, e);
hasException = true;
} finally {
executeTaskFinally(hasException, tw);
tw.setThread(null);
if (tw.getCRToken() != null) {
crController.releaseToken(tw.getCRToken());
tw.setCRToken(null);
}
TaskWrapper.taskWrapperContext.set(null);
Logger.reset();
}
}
/**
* 执行时发生异常。
*
* @param task
* @param e
*/
private void executeTaskException(TaskWrapper tw, Exception e) {
if (e != null) {
logExecuteTaskException(tw, e);
} else {
try {
tw.getTask().getTaskBody().cancelExecute();
} catch (Exception ex) {
logException(ex);
}
}
bgProcess(tw, false, e);
}
/**
* 任务执行完毕,将该任务的对象引用设置为<tt>null</tt>,并且通知由执行器池来处理该执行器。
*
* @return
*/
private void executeTaskFinally(boolean hasException, TaskWrapper tw) {
if (!hasException) {
bgProcess(tw, false, null);
}
RemoteProcessComponetFactory factory = getRemoteProcessComponetFactory();
if (factory != null) {
factory.clearThreadScopePostProcess();
}
try {
IAttributeManager requestAttrMgr = getAttributeManager();
if (requestAttrMgr != null) {
requestAttrMgr.clear();
}
} catch (Throwable thr) {
Messages.log.error("Background executeTaskFinally error", thr);
}
}
/**
* 如果该任务为<tt>null</tt>,则只等待一个超时时间。
*/
private void manageNullTask() {
synchronized (this) {
if (getTaskWrapper() == null) {
try {
wait(pool.getExecutorIdleTimeOut());
} catch (InterruptedException e) {
logException(e);
}
}
}
}
/**
* 将任务传给任务执行器,并唤醒之(由线程池调用)。
*
* @param taskWrapper
* 任务包装类,包括任务ID,任务对象,任务优先级
*/
synchronized void execute(TaskWrapper taskWrapper) {
setTaskWrapper(taskWrapper);
notifyAll();
}
public TaskWrapper getTaskWrapper() {
return taskWrapper;
}
private void setTaskWrapper(TaskWrapper taskWrapper) {
this.taskWrapper = taskWrapper;
}
private void logBeginExecute(TaskWrapper tw) {
Messages.log.debug("Begin " + tw);
}
/**
* 对任务的执行产生的异常进行记录。
*
* @param task
* @param e
*/
private void logExecuteTaskException(TaskWrapper tw, Exception e) {
Messages.log.error("Error execute " + tw, e);
}
/**
* 对异常进行记录。
*
* @param e
*/
private void logException(Throwable e) {
Messages.log.warn(Messages.getString("TaskExecutor.exception"), e);
}
/**
* 对任务执行完毕进行记录。
*
* @param e
*/
private void logExecuteFinished(TaskWrapper tw, long time) {
Messages.log.debug("Finished " + tw + " spend time: " + time);
}
private RemoteProcessComponetFactory getRemoteProcessComponetFactory() {
if (factory == null) {
try {
factory = (RemoteProcessComponetFactory) NCLocator
.getInstance().lookup("RemoteProcessComponetFactory");
} catch (Throwable thr) {
Logger.error("Maybe the BizServer has not been started", thr);
}
}
return factory;
}
private IAttributeManager getAttributeManager() {
if (requestAttrMgr == null) {
try {
requestAttrMgr = (IAttributeManager) NCLocator
.getInstance()
.lookup(
"nc.bs.framework.core.service.RequestAttributeManager");
} catch (Throwable thr) {
Logger.error("Maybe the BizServer has not been started", thr);
}
}
return requestAttrMgr;
}
private void bgProcess(TaskWrapper tw, boolean pre, Throwable t) {
try {
RemoteProcessComponetFactory factory = getRemoteProcessComponetFactory();
if (factory != null) {
if (pre) {
factory.preProcess();
} else {
if (t == null) {
factory.postProcess();
} else {
factory.postErrorProcess(t);
}
}
}
} catch (Throwable thr) {
Messages.log.error("Background process error", thr);
}
}
}