package org.hy.common.thread; import org.hy.common.Date; import org.hy.common.StringHelp; import org.hy.common.thread.ui.ThreadPoolWatch; import org.hy.common.thread.ui.WatchTableColumnIndex; /** * 通用线程类 * * @author ZhengWei(HY) * @version V1.0 2011-06-08 * V1.1 2018-08-24 修复:防止在队列中长时间等待的线程,在濒临死亡的一瞬间,被当作空闲线程使用 */ public class ThreadBase { protected static long SERIALNO = 0; /** 线程编号 */ protected String threadNo; /** 线程实例对象 */ protected Thread thread; /** 内核线程对象 */ protected CoreThread coreThread; /** 任务对象 */ protected Task<?> taskObject; /** 前一个任务对象的任务类型 */ protected String oldTaskType; /** 线程是否在运行 */ protected boolean isRun = false; /** 线程是否暂停(挂起) */ protected boolean isPause = false; /** 是否有任务在身 */ protected boolean isHaveTask = false; /** 线程运行状态 */ protected ThreadRunStatus threadRunStatus; /** 等待时间间隔(单位:毫秒) */ protected long intervalTime; /** 空闲多少时间后线程自毁(单位:秒) */ protected long idleTimeKill; /** 执行任务次数 */ protected long executeTaskCount; /** 任务开始执行时间 */ protected Date taskStartTime; /** 任务结束时间 */ protected Date taskEndTime; /** 所有任务累计用时 */ protected long totalTime; /** 线程在视窗化窗口的表格中的行位置(下标从零开始) */ protected int watchTableRowIndex; /** 线程附加缓存。是预留给继承者使用的。继承者可以有选择的使用。 */ protected Object cache; protected synchronized static long getSerialNo() { return ++SERIALNO; } public ThreadBase() { this(null); } public ThreadBase(Task<?> i_TaskObject) { this(i_TaskObject ,100 ,60); } /** * 构造器 * * @param i_TaskObject 任务对象 * @param i_IntervalTime 等待时间间隔(单位:毫秒) 默认为:100毫秒 * @param i_IdleTimeKill 空闲多少时间后线程自毁(单位:秒) 默认为:60秒 */ public ThreadBase(Task<?> i_TaskObject ,long i_IntervalTime ,long i_IdleTimeKill) { this.setIdleTimeKill(i_IdleTimeKill); this.setIntervalTime(i_IntervalTime); this.threadNo = "线程号-" + getSerialNo(); this.executeTaskCount = 0; this.totalTime = 0; this.threadRunStatus = ThreadRunStatus.$Init; this.taskStartTime = null; this.taskEndTime = null; if ( ThreadPool.isWatch() ) { this.watchTableRowIndex = ThreadPoolWatch.getInstance().addRow(this); } this.setTaskObject(i_TaskObject); } public String getThreadNo() { return this.threadNo; } public String getOldTaskType() { return this.oldTaskType; } public Object getCache() { return cache; } public void setCache(Object cache) { this.cache = cache; } public long getExecuteTaskCount() { return this.executeTaskCount; } public Date getTaskStartTime() { return this.taskStartTime; } public Date getTaskEndTime() { return this.taskEndTime; } public long getTotalTime() { return this.totalTime; } public String getTotalTimeSec() { return StringHelp.doubleParse(this.totalTime / 1000d, 2); } public long getIntervalTime() { return intervalTime; } public void setIntervalTime(long i_IntervalTime) { if ( i_IntervalTime > 0 ) { this.intervalTime = i_IntervalTime; } } public long getIdleTimeKill() { return idleTimeKill; } public void setIdleTimeKill(long idleTimeKill) { if ( idleTimeKill > 0 ) { this.idleTimeKill = idleTimeKill; } } public String getThreadRunStatusName() { return threadRunStatus.getName(); } public synchronized ThreadRunStatus getThreadRunStatus() { return threadRunStatus; } /** * 内部使用 * * @param i_ThreadTaskRunStatus */ protected synchronized void setThreadRunStatus(ThreadRunStatus i_ThreadTaskRunStatus) { setThreadRunStatus_NoSync(i_ThreadTaskRunStatus); } /** * 内部使用的,并且调用此方法的父方法有同步锁synchronized,所以此方法不再添加同步锁synchronized。 * * @author ZhengWei(HY) * @createDate 2018-08-23 * @version v1.0 * * @param i_ThreadTaskRunStatus */ private void setThreadRunStatus_NoSync(ThreadRunStatus i_ThreadTaskRunStatus) { this.threadRunStatus = i_ThreadTaskRunStatus; if ( this.threadRunStatus.equals(ThreadRunStatus.$Working) ) { this.taskStartTime = new Date(); this.taskEndTime = null; } else if ( this.threadRunStatus.equals(ThreadRunStatus.$Finish) ) { this.taskEndTime = new Date(); this.totalTime = this.totalTime + (this.taskEndTime.getTime() - this.taskStartTime.getTime()); } if ( ThreadPool.isWatch() ) { // 及时更新视窗化监视窗口的信息 ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$RunStatus ,this.threadRunStatus.toString()); if ( this.threadRunStatus.equals(ThreadRunStatus.$Finish) ) { ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$ExecCount ,String.valueOf(this.executeTaskCount)); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TotalTime ,this.getTotalTimeSec()); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskDesc ,this.taskObject.getTaskDesc()); } } } public Task<?> getTaskObject() { return taskObject; } public void setTaskObject(Task<?> taskObject) { this.taskObject = taskObject; if ( ThreadPool.isWatch() ) { // 及时更新视窗化监视窗口的信息 if ( this.taskObject != null ) { this.taskObject.setThread(this); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskName ,this.taskObject.getTaskName()); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskDesc ,this.taskObject.getTaskDesc()); } else { ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskName ," "); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskDesc ," "); } } else { if ( this.taskObject != null ) { this.taskObject.setThread(this); } } } /** * 刷新一下监视窗口中的信息 */ public void refreshWatchInfo() { if ( ThreadPool.isWatch() ) { ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$RunStatus ,this.threadRunStatus.toString()); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$ExecCount ,String.valueOf(this.executeTaskCount)); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TotalTime ,this.getTotalTimeSec()); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskName ,this.taskObject.getTaskName()); ThreadPoolWatch.getInstance().updateRow(this.watchTableRowIndex ,WatchTableColumnIndex.$TaskDesc ,this.taskObject.getTaskDesc()); } } public boolean isRun() { return isRun; } public boolean isPause() { return isPause; } public boolean isHaveTask() { return isHaveTask; } // 待删除 @Deprecated public void notPause() { // if ( !this.isPause ) // { // this.isPause = true; // } } // 待删除 @Deprecated public void newTask() { // this.isHaveTask = true; } // 待删除 @Deprecated public void newTask(Task<?> i_TaskObject) { // this.isHaveTask = true; // this.setTaskObject(i_TaskObject); } // 待删除 @Deprecated public void stopRun() { // this.isRun = false; } /** * 启动线程 * * 指线程已运行,但具体任务还没有执行,需要调用 executeTask() 方法执行。 * * @return */ public boolean startup() { if ( this.isRun() ) { return true; } else { return this.changeStatus(ThreadControlStatus.$Starting); } } /** * 启动线程并执行任务 * */ public synchronized boolean startupAndExecuteTask() { boolean v_Ret = false; v_Ret = this.startup(); if ( v_Ret ) { v_Ret = this.executeTask(); } return v_Ret; } /** * 执行任务 * * @return */ public boolean executeTask() { return this.changeStatus(ThreadControlStatus.$Executing); } /** * 任务执行完成 * * @return */ public boolean finishTask() { return this.changeStatus(ThreadControlStatus.$Finishing); } /** * 线程空闲 * * @return */ public boolean rest() { return this.changeStatus(ThreadControlStatus.$Resting); } /** * 关闭线程 * * @return */ public boolean shutdown() { return this.changeStatus(ThreadControlStatus.$Shutdowning); } /** * 设置线程状态的统一方法(对所有public、protected方法)。 * * 注意:只能用这个方法设置,不能直接访问具体的变量进行设置 * * 返回值表示:是否设置成功 */ protected synchronized boolean changeStatus(ThreadControlStatus i_ThreadStatus) { boolean v_Ret = false; if ( ThreadControlStatus.$Starting.equals(i_ThreadStatus) ) { v_Ret = this.toStartupStatus(); if ( v_Ret ) { if ( this.thread == null ) { this.coreThread = new CoreThread(this); this.thread = new Thread(this.coreThread); this.thread.start(); } } } else if ( ThreadControlStatus.$Executing.equals(i_ThreadStatus) ) { v_Ret = this.toExecuteStatus(); } else if ( ThreadControlStatus.$Finishing.equals(i_ThreadStatus) ) { v_Ret = this.toFinishStatus(); if ( v_Ret ) { this.setThreadRunStatus_NoSync(ThreadRunStatus.$Finish); this.executeTaskCount++; ThreadPool.addIdleThread(this); } } else if ( ThreadControlStatus.$Resting.equals(i_ThreadStatus) ) { v_Ret = this.toRestStatus(); if ( v_Ret ) { this.setThreadRunStatus_NoSync(ThreadRunStatus.$Rest); ThreadPool.addIdleThread(this); } } else if ( ThreadControlStatus.$Shutdowning.equals(i_ThreadStatus) ) { int v_RetCode = ThreadPool.killMySelf(this); if ( v_RetCode == 0 ) { v_Ret = this.toShutdownStatus(); } else { return false; } if ( v_Ret ) { this.setThreadRunStatus_NoSync(ThreadRunStatus.$Kill); if ( this.taskObject != null ) { this.taskObject = null; } if ( this.thread != null ) { try { if ( !this.thread.isInterrupted() ) { this.thread.interrupt(); } } catch (Throwable exce) { exce.printStackTrace(); } this.thread = null; } if ( this.coreThread != null ) { this.coreThread = null; } } } return v_Ret; } /** * 变为启动状态,空转不执行任务 * * 不用加 synchronized 同步锁,因为调用执行本的方法已经是同步的,并且只有一处调用执行此方法 */ private boolean toStartupStatus() { return this.setAllStatus(false ,false ,false ,true ,true ,false); // 【运行】线程,【无任务】,为【暂停】空转的状态 } /** * 变为执行状态 * * 不用加 synchronized 同步锁,因为调用执行本的方法已经是同步的,并且只有一处调用执行此方法 */ private boolean toExecuteStatus() { return this.setAllStatus(true ,true ,false ,true ,false ,true); // 【运行】线程,【有任务】,从【暂停】转【执行】的状态 } /** * 变为执行完成状态 * * 不用加 synchronized 同步锁,因为调用执行本的方法已经是同步的,并且只有一处调用执行此方法 */ private boolean toFinishStatus() { return this.setAllStatus(true ,false ,true ,true ,true ,false); // 【运行】线程,【无任务】,从【执行】转【暂停】的状态 } /** * 变为空闲状态 * * 不用加 synchronized 同步锁,因为调用执行本的方法已经是同步的,并且只有一处调用执行此方法 */ private boolean toRestStatus() { return this.setAllStatus(true ,false ,true ,true ,true ,false); // 【运行】线程,【无任务】,从【执行】转【暂停】的状态 } /** * 变为停止运行状态 * * 不用加 synchronized 同步锁,因为调用执行本的方法已经是同步的,并且只有一处调用执行此方法 */ private boolean toShutdownStatus() { boolean v_Ret = this.setAllStatus(true ,false ,true ,false ,true ,false); // 【执行中】转【停止】线程 if ( v_Ret ) { return true; } return this.setAllStatus(true ,true ,false ,false ,true ,false); // 【运行】 转【停止】线程 // 【执行完成】转【停止】线程 } /** * 设置线程所有标记的统一方法(对所有private方法)。 * * 注意:只能用这个方法设置,不能直接访问具体的变量进行设置 * * 在设置前,须进行验证。验证通过对所有标记进行设置,只要有一个标记没有验证通过,侧所有标记都不进行设置 * * 返回值表示:是否设置成功 * * 不用加 synchronized 同步锁,因为调用执行本的方法已经是同步的,并且只有一处调用执行此方法 */ private boolean setAllStatus(boolean i_Old_IsRun ,boolean i_Old_IsPause ,boolean i_Old_IsHaveTask ,boolean i_New_IsRun ,boolean i_New_IsPause ,boolean i_New_IsHaveTask) { if ( i_Old_IsRun == this.isRun ) { if ( i_Old_IsPause == this.isPause ) { if ( i_Old_IsHaveTask == this.isHaveTask ) { this.isRun = i_New_IsRun; this.isPause = i_New_IsPause; this.isHaveTask = i_New_IsHaveTask; return true; } } } return false; } /** * 设置内核线程,重新计算其空闲时间 * * @author ZhengWei(HY) * @createDate 2018-08-24 * @version v1.0 * * @return */ public boolean coreIdleTimeRecalculation() { if ( this.coreThread != null ) { this.coreThread.setIdleBeginTime(0); return true; } return false; } public void finalize() { this.shutdown(); } class CoreThread implements Runnable { private ThreadBase myThreadBase; private long idleBeginTime; public CoreThread(ThreadBase i_MyThreadBase) { this.myThreadBase = i_MyThreadBase; this.idleBeginTime = 0; } public void run() { this.idleBeginTime = 0; while ( this.myThreadBase.isRun() ) { if ( this.myThreadBase.isPause() || !this.myThreadBase.isHaveTask() ) { try { // 记录空闲时间,并在空闲时间最大值后,线程自毁 if ( this.idleBeginTime == 0 ) { this.idleBeginTime = System.currentTimeMillis(); this.myThreadBase.setThreadRunStatus(ThreadRunStatus.$Rest); } else { // 判断是否达到空闲时间后线程自毁 if ( (System.currentTimeMillis() - this.idleBeginTime) >= (this.myThreadBase.getIdleTimeKill() * 1000) ) { if ( this.myThreadBase.shutdown() ) { return; } else { // 如果没有销毁线程,就重新计算其空闲时间 // 防止在队列中长时间等待的线程,在濒临死亡的一瞬间,被当作空闲线程使用 ZhengWei(HY) Add 2018-08-24 this.idleBeginTime = 0; } } } } catch (Exception exce) { exce.printStackTrace(); } ThreadPool.sleep(this.myThreadBase.getIntervalTime()); } else { try { if ( this.myThreadBase.getTaskObject() != null ) { this.idleBeginTime = 0; this.myThreadBase.setThreadRunStatus(ThreadRunStatus.$Working); this.myThreadBase.oldTaskType = new String(this.myThreadBase.getTaskObject().getTaskType()); // 执行任务 this.myThreadBase.taskObject.run(); this.myThreadBase.setThreadRunStatus(ThreadRunStatus.$Finish); } else { this.myThreadBase.rest(); } } catch (Exception exce) { exce.printStackTrace(); this.myThreadBase.rest(); } } } } public long getIdleBeginTime() { return idleBeginTime; } public void setIdleBeginTime(long idleBeginTime) { this.idleBeginTime = idleBeginTime; } } }