多线程开发 知识点作者张全胜.docx
- 文档编号:30511547
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:21
- 大小:78.25KB
多线程开发 知识点作者张全胜.docx
《多线程开发 知识点作者张全胜.docx》由会员分享,可在线阅读,更多相关《多线程开发 知识点作者张全胜.docx(21页珍藏版)》请在冰豆网上搜索。
多线程开发知识点作者张全胜
多线程开发2012-2-8现在的理解
多线程开发的好处:
为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而互不干扰,如当前进程要完成三件事情1、2、3,那么CPU会分别用10%的时间来同时处理这3件事情,从而让CPU的使用率达到了30%,大大地提高了CPU的利用率。
多线程的好处在处理一些特殊的场合其优势尤其明显。
比如下载文件,你要一边下载一边显示进度一边保存,在这种情况下,如果没有用多线程的话,没有意外的话一般都会把主线程阻塞,比如进度条的进度根本没有随着已下载的量而变化,堪至是整个窗体都动不了,用多线程就可以很好地解决这个问题。
什么时候使用多线程:
了解了多线程的好处以后,就要了解应该在什么样的情况下使用多线程技术。
因为并不是说所有情况下用多线程都是好事,因为多线程的情况下,CPU还要花时间去维护,CPU处理各线程的请求时在线程间的切换也要花时间,所以一般情况下是可以不用多线程的,用了有时反而会得不偿失。
大多情况下,要用到多线程的主要是需要处理大量的IO操作时或处理的情况需要花大量的时间等等,比如:
读写文件、视频图像的采集、处理、显示、保存等。
主要还是看看我在hadoop中使用的多线程开发:
我在hadoop中使用了多线程开发,主要是解决报表模板生成报表的功能,大量的报表可以再规定的时间点开始执行生成报表操作。
我把报表模板生成报表作为一个任务,那首先要建立这个任务,这个被称为采集任务。
任务采集完成后,在规定的时间就会多线程的执行这些任务。
下面就细细的看看这个多线程是怎样执行的。
首先要初始化线程池:
ThreadPoolthreaPool=newThreadPoolImpl();
threaPool.initThreadPool();
publicinterfaceThreadPool{
/**
*初始化线程池
*@throwsException
*/
publicvoidinitThreadPool()throwsException;
}
publicclassThreadPoolImplimplementsThreadPool{
publicvoidinitThreadPool()throwsException{
try{
System.out.println("开始创建线程池-->");
System.out.println("1).核心线程数:
"+ThreadConstant.corePoolSize);
System.out.println("2).最大线程数:
"+ThreadConstant.maximumPoolSize);
System.out.println("3).空闲时间:
"+ThreadConstant.keepAliveTime+"秒");
System.out.println("4).阻塞队列数:
"+ThreadConstant.workQueue+"个");
//构造一个线程池
ThreadPoolExecutor_threPoolExecutor=newThreadPoolExecutor(
ThreadConstant.corePoolSize,
ThreadConstant.maximumPoolSize,
ThreadConstant.keepAliveTime,
ThreadConstant.unit,
ThreadConstant.workQueue,
ThreadConstant.handler
);
ThreadConstant.threadPoolExecutor=_threPoolExecutor;
if(ThreadConstant.threadPoolExecutor!
=null)
System.out.println("创建完毕!
");
else
System.out.println("创建失败!
");
}catch(Exceptione){
throwe;
}
}
}
//ThreadConstant线程池常量可以自己设置,这里就不把代码拿出来了
可以上网查查ThreadPoolExecutor是什么意思?
资料1:
然后看看管理任务的接口与实现类
/**
*任务管理-业务类
*@authorAdministrator
*
*/
publicinterfaceJobTaskService{
/**
*获取任务
*该方法单独启线程,定时从表中加载任务列表。
*/
publicbooleantoGetJobTasks()throwsException;
/**
*执行任务
*该方法单独启线程,定时从任务列表中获取任务,并传参于任务执行程序。
*/
publicvoidtoRunJobTasks(TblJobtaskstblCfgJobtasks);
/**
*暂停任务
*/
publicvoidtoPauseJobTasks(TblJobtaskstblCfgJobtasks);
/**
*终止任务
*/
publicvoidtoStopJobTasks(TblJobtaskstblCfgJobtasks);
/**
*移除任务
*/
publicvoidtoRemoveJobTasks(TblJobtaskstblCfgJobtasks);
/**
*立即结束
*@paramtblCfgJobtasks
*/
publicvoidtoFinishJobTasks(TblJobtaskstblCfgJobtasks);
/**
*重新运行任务
*@paramtblCfgJobtasks
*/
publicvoidtoRestartJobTasks(TblJobtaskstblCfgJobtasks);
/**
*更新没有子任务的任务包
**/
publicvoidtoUpdateEmptyFolders();
}
实现类:
后面有注释的
publicclassJobTaskServiceImplimplementsJobTaskService{
publicLoggerlogger=Logger.getLogger(JobTaskServiceImpl.class);
publicbooleantoGetJobTasks(){//名字可以看出是去得到任务
try{
JobTasksDaojobTaskDao=newJobTasksDao();
booleanisStart=false;
if(JobTasksContant.tblCfgJobtasksLs==null)//为空表示首次启动
isStart=true;
JobTasksContant.tblCfgJobtasksLs=jobTaskDao.getJobTasksList(isStart);//这里又要去看jobTaskDao.getJobTasksList这个函数了,我就直接说明功能:
通过参数是否运行去采集不同的任务,如果isStart=true;则也要采集正在运行的线程任务(这些都是任务的状态,在数据库中有字段表示)。
采集的任务返回List
returntrue;
}catch(Exceptione){
e.printStackTrace();
}
returnfalse;
}
publicvoidtoRunJobTasks(TblJobtaskstblCfgJobtasks){
//执行任务,也知道TblJobtasks为任务的bean类,一个对象就是表示一个任务(任务对象)
JobTasksDaojobtasksdao=newJobTasksDao();
ThreadWorkerthreadWorder=null;
try{
System.out.println("开始添加任务至线程池-->");
System.out.println("核心线程数:
"+ThreadConstant.threadPoolExecutor.getCorePoolSize());
System.out.println("最大线程数:
"+ThreadConstant.threadPoolExecutor.getMaximumPoolSize());
System.out.println("已激活线程数:
"+ThreadConstant.threadPoolExecutor.getActiveCount());
System.out.println("已完成线程数:
"+ThreadConstant.threadPoolExecutor.getCompletedTaskCount());
System.out.println("当前线程数:
"+ThreadConstant.threadPoolExecutor.getPoolSize());
if(tblCfgJobtasks.getTasksDepid()==null||tblCfgJobtasks.equals("0")||tblCfgJobtasks.getTasksDepid()==null||"N/A".equals(tblCfgJobtasks.getTasksDepid())||jobtasksdao.canJobTasksRun(tblCfgJobtasks.getTasksDepid()))
{//以上if中的条件可以自己设置,不用管他
jobtasksdao.updateJobTasksState(tblCfgJobtasks,"RUNNING");
//修改此任务的状态,为正在运行中RUNNING
StringrunAppName=tblCfgJobtasks.getRunAppname();
//这个是说明这个任务应该使用哪个任务实例去实现Universally表示通用
if(runAppName.startsWith("Universally:
")){
threadWorder=newUniversallyImpl(tblCfgJobtasks.getRunAppname());
}elseif(runAppName.startsWith("Sqoop:
")){
threadWorder=newSqoopImpl(tblCfgJobtasks.getRunAppname());
}elseif(runAppName.startsWith("N/A")){
jobtasksdao.updateJobTasksState(tblCfgJobtasks,"FINISHED");
}else{
threadWorder=(ThreadWorker)Class.forName(tblCfgJobtasks.getRunAppname()).newInstance();//通过反射机制,动态加载类文件
}
threadWorder.initThreadWorker(tblCfgJobtasks);//初始工作线程参数
ThreadConstant.threadPoolExecutor.execute(threadWorder);//运行工作线程
}
return;
}catch(ClassNotFoundExceptione){
System.out.println(tblCfgJobtasks.getTasksId());
logger.error(e);
}catch(InstantiationExceptione){
System.out.println(tblCfgJobtasks.getTasksId());
logger.error(e);
}catch(IllegalAccessExceptione){
System.out.println(tblCfgJobtasks.getTasksId());
logger.error(e);
}catch(RejectedExecutionExceptione){
System.out.println(tblCfgJobtasks.getTasksId());
logger.error("任务队列已满,添加异常!
",e);
}catch(Exceptione){
System.out.println(tblCfgJobtasks.getTasksId());
logger.error(e);
}
//最终更新任务状态
try{
tblCfgJobtasks.setRunLastmemo("Error!
");//如果任务最后没有执行,则放弃继续采集,把他的状态设为FAILED因为这里也会采集running的所以这就有一个次数限制,如果这个任务被采集了3此以后还没有完成,则设为此状态FAILED
jobtasksdao.updateJobTasksState(tblCfgJobtasks,"FAILED");
}catch(Exceptione){
logger.error(e);
}
}
publicvoidtoPauseJobTasks(TblJobtaskstblCfgJobtasks){
Longkey=tblCfgJobtasks.getTasksId();
}
publicvoidtoStopJobTasks(TblJobtaskstblCfgJobtasks){
if(tblCfgJobtasks.getTasksState()=="FINISH")return;
JobTasksDaojobTaskDao=newJobTasksDao();
try{
jobTaskDao.updateJobTasksState(tblCfgJobtasks,"FAILED");
//jobTaskDao.updateDependent(tblCfgJobtasks.getTasksId());
}catch(Exceptione){
e.printStackTrace();
}
}
publicvoidtoRestartJobTasks(TblJobtaskstblCfgJobtasks)
{
JobTasksDaojobTaskDao=newJobTasksDao();
try{
jobTaskDao.updateJobTasksState(tblCfgJobtasks,"WAITING");
//jobTaskDao.updateDependent(tblCfgJobtasks.getTasksId());
}catch(Exceptione){
e.printStackTrace();
}
}
publicvoidtoRemoveJobTasks(TblJobtaskstblCfgJobtasks){
//Longkey=tblCfgJobtasks.getTasksId();
JobTasksDaojobTaskDao=newJobTasksDao();
try{
jobTaskDao.removeTask(tblCfgJobtasks);
//jobTaskDao.updateDependent(tblCfgJobtasks.getTasksId());
}catch(Exceptione){
e.printStackTrace();
}
}
publicvoidtoFinishJobTasks(TblJobtaskstblCfgJobtasks)
{//只是当任务执行成功后,设置该任务为FINISHED
JobTasksDaojobTaskDao=newJobTasksDao();
try{
jobTaskDao.updateJobTasksState(tblCfgJobtasks,"FINISHED");
//jobTaskDao.updateDependent(tblCfgJobtasks.getTasksId());
}catch(Exceptione){
e.printStackTrace();
}
}
publicvoidtoUpdateEmptyFolders()
{
JobTasksDaojobtasksdao=newJobTasksDao();
jobtasksdao.updateEmptyParTaskState();
}
}
在程序中是这样取出所有的任务的:
到这里所有的任务都执行了,通过toRunJobTasks执行,然后每个一分钟在执行同样的动作。
那怎样实现多线程的呢?
那就在细细看看toRunJobTasks这个方法了。
记得在这个方法下有这样一句话:
所以在可以看看UniversallyImpl这个类,他就是一个任务线程类。
源代码如下:
publicclassUniversallyImplextendsBaseThreadWorkerImplimplementsThreadWorker{
//日志配置
privateLoggerlogger=Logger.getLogger(UniversallyImpl.class);
privateStringappType=null;//应用程序类型
privateStringappPath=null;//应用程序路径
publicUniversallyImpl(StringappName){
String[]appNameStrArr=appName.split("Universally:
");
Stringapp=appNameStrArr[1];
String[]appStrArr=app.split("@=");
this.appType=appStrArr[0];
this.appPath=appStrArr[1];
}
/*
*内部类
*/
privateclassUniversallyDao{
BaseDaobaseDao=newBaseDaoImpl();
publicbooleanexcuteCommand(DBInfosourceDataDBInfo,StringcallProcedureSQL,ArrayList
try{
returnbaseDao.executeSQLByPool(sourceDataDBInfo,callProcedureSQL,parmsLs);
}catch(Exceptione){
throwe;
}
}
publicbooleancallSourceProcedure(DBInfosourceDataDBInfo,StringcallProcedureSQL,ArrayList
try{
returnbaseDao.executeProcedureByPool(sourceDataDBInfo,callProcedureSQL,parmsLs);
}catch(Exceptione){
throwe;
}
}
publicList
//TODOAuto-generatedmethodstub
returnnull;
}
publicintcountSourceData(DBInfosourceDataDBInfo,StringquerySourceSql,ArrayList
//TODOAuto-generatedmethodstub
return0;
}
publicvoiddeleteTargetData(DBInfotargetDataDBInfo,StringdeleteTargetSQL,ArrayList
//TODOAuto-generatedmethodstub
}
publicbooleaninsertTargetData(DBInfotargetDataDBInfo,StringinsertTargetSql,List
//TODOAuto-generatedmethodstub
returnfalse;
}
}
pr
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 多线程开发 知识点作者张全胜 多线程 开发 知识点 作者 全胜