我们有一个守护进程,必须每次执行并查找要处理的新请求。因为我们有5个服务器需要执行该进程,所以当前守护程序进程通过使用执行服务的newFixedThreadPool创建5个线程。一旦工作完成,我们就会关闭执行者。
当这个作业部署在生产的unix服务器上时,经过几天的运行就会挂起来。通过日志,我们看到所有执行程序线程都已完成了他们的工作但是在执行关闭之后它被挂起了。我假设在这种情况下,执行器没有正常关闭,因为我们正在检查它是否在for循环中终止。该循环可以无限运行,因此无需进一步处理。请分享您的想法可能是另一个原因。
代码:
do {
executor = Executors.newFixedThreadPool(5);
startTime=System.currentTimeMillis();
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)!='-'||str.charAt(i)!=','||str.charAt(i)!='.'||str.charAt(i)!='|') {
if(str.charAt(i)=='5'||str.charAt(i)=='6'||str.charAt(i)=='7'||str.charAt(i)=='8'||str.charAt(i)=='9') {
String s=str.substring(i, i+1);
Runnable worker = new ExecuteThread(s,batchtype);
executor.execute(worker);
}
}
}
executor.shutdown();
while (!executor.isTerminated()) { }
} while(batchtype == 2);
为了解决这个问题,我现在已经包含了shutdownNow方法,并且正在考虑删除无限循环,我们正在检查执行程序是否已终止。如果以下代码足以遏制错误,请分享您的观点。
do {
executor = Executors.newFixedThreadPool(5);
startTime=System.currentTimeMillis();
for (int i = 0; i < str.length(); i++) {
if(str.charAt(i)!='-'||str.charAt(i)!=','||str.charAt(i)!='.'||str.charAt(i)!='|') {
if(str.charAt(i)=='5'||str.charAt(i)=='6'||str.charAt(i)=='7'||str.charAt(i)=='8'||str.charAt(i)=='9') {
String s=str.substring(i, i+1);
Runnable worker = new ExecuteThread(s,batchtype);
executor.execute(worker);
}
}
}
executor.shutdown();
// FIX
try {
if (!executor.awaitTermination(900,TimeUnit.SECONDS)) {
logger.info("Executor did not terminate in the specified time.");
List<Runnable> droppedTasks = executor.shutdownNow();
if (!executor.awaitTermination(600,TimeUnit.SECONDS)){
logger.info("Even shutdownNow did not terminated in the specified time.");
}
logger.info("Executor abruptly shut down. " + droppedTasks.size() + " tasks will not be executed.");
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
logger.error(e.getMessage());
}
//while (!executor.isTerminated()) {
//}
stopTime=System.currentTimeMillis();
logger.info("Time taken by executer to finish job with batchType "+batchtype+ " in sec " +(stopTime-startTime)/1000);
} while(batchtype==2);// to run batch-2 in daemon mode
执行线程代码:
public class ExecuteThread extends AbstractMaxisBatchSystem implements Runnable {
private String serverId;
private int batchtype;
public ExecuteThread(String s,int batchtype) throws MaxisBatchFatalException {
this.serverId=s;
this.batchtype=batchtype;
}
private static Logger logger = null;
static{
try{
logger = logger.getLogger(com.maxis.rnb.batch.realReinstatement.FetchNewPayments.ExecuteThread.class);
}
catch(Exception ex) { }
}
/*public ExecuteThread(String s, int batchtype2) throws MaxisBatchFatalException{
// TODO Auto-generated constructor stub
}*/
public void run()
{
try
{
if(batchtype==1)
{
logger.info("FetchNewPayment Batch started for serverID: " +serverId);
FetchNewPayment batch = new FetchNewPayment();
batch.execute(serverId);
}
else if(batchtype==2)
{
//do{
logger.info("ProcessNewPayment Batch started for serverID: " +serverId);
ProcessNewPayment batch = new ProcessNewPayment();
batch.execute(serverId);
//}
//while(true);
}
else if(batchtype==3)
{
logger.info("HouseKeeping Batch started for serverID: " +serverId);
RRHouseKeeping batch = new RRHouseKeeping();
batch.execute(serverId);
}
}
catch (MaxisBatchFatalException e)
{
logger.error("ServerId: "+serverId+":"+e.getMessage(), e);
// System.exit(EXIT_FATAL);
//throw new MaxisBatchFatalException(e.getMessage(), e);
}
}
}