我们系统中经常有耗费时间长的任务,但客户端往往需要马上得到回应。这时我们就可以如下步骤实现:
1、客户端发起请求执行任务(选定条件,下载报表);
2、首先将任务ID及开始时间,起始状态记录到数据库表中;
3、另起一个后台线程去执行这个耗时任务(比如生成报表);
4、线程执行成功或失败状态记录到数据库;
5、客户通过异步查询数据(下载报表或其他操作)。
好了,大致步骤我们清楚了。假如这个耗时任务一直执行,而且和消耗系统资源。我们往往想放弃这个任务的执行,再缩小范围执行更小的任务执行。那我们如何实现呐!
话不多说,直接上代码:
1.首先我们实现一个线程管理工具:
import java.sql.DriverManager
import java.util.concurrent.ConcurrentHashMap
import org.slf4j.LoggerFactory
import scala.util.{Failure, Success, Try}
/**
* 类功能描述:报表线程管理器
*
* @author WangXueXing create at 18-11-2 上午11:35
* @version 1.0.0
*/
object ReportThreadManager {
private val logger = LoggerFactory.getLogger(getClass)
/**
* 报表ID与对应线程map
*/
val REPORT_THREAD_MAP: ConcurrentHashMap[Long, Thread] = new ConcurrentHashMap()
/**
* 将对应报表子线程放入线程池
*
* @param reportId 报表ID
* @param thread 对应子线程
*/
def put(reportId: Long, thread: Thread): Unit = {
REPORT_THREAD_MAP.put(reportId, thread)
}
/**
* 获取对应报表线程
* @param reportId 报表ID
* @return
*/
def get(reportId: Long): Thread ={
REPORT_THREAD_MAP.get(reportId)
}
/**
* 将对应报表子线程移除线程池
* @param reportId 报表ID
*/
def remove(reportId: Long): Unit ={
REPORT_THREAD_MAP.remove(reportId)
}
/**
* 销毁指定报表子线程
* @param reportId 报表ID
*/
def deploy(reportId: Long)={
val thread = REPORT_THREAD_MAP.get(reportId)
if(thread != null){
Try{
if(!thread.isInterrupted){
logger.info(s"线程:${reportId} 开始被结束")
logger.info("before interrupt")
thread.getStackTrace.fore