黑马程序员技术交流社区
标题:
让线程实现暂停,重新启动,停止(工作经验)
[打印本页]
作者:
马进
时间:
2012-7-29 00:52
标题:
让线程实现暂停,重新启动,停止(工作经验)
本帖最后由 马进 于 2012-7-29 00:56 编辑
大家都知道线程执行体run()方法一旦执行完毕,线程就会退出,同时JVM会释放掉线程占用的所有资源,让线程呈现出一中只读状态。在处理数据来源不确定,处理时间不确定的场景下就无法保证线程的合理运作。由于JDK提供的线程暂停是非线程安全的,可能造成死锁,已经被不推荐使用,这样我们就需要一种机制对线程做暂停,重新启动,停止等操作。以下是我写的一段代码,从工作经验中所得。
public class BaseThread extends Thread{
private final static Logger logger = Logger.getLogger(BaseThread.class);
/**
* isDead:是否杀死线程
*/
private boolean isDead = false;
/**
* isStop:是否停止
*/
private boolean isStop = false;
/**
* isRun:是否已开始执行
*/
private boolean isRun = false;
/**
* isWait:是否处于等待
*/
private boolean isSleep = false;
public BaseThread() {
super();
this.setDaemon(false);//设置为非守护线程
logger.info("线程:["+this.getId()+"] 被创建");
}
public BaseThread(String threadName) {
super(threadName);
this.setDaemon(false);//设置为非守护线程
logger.info("线程:["+threadName+"-"+this.getId()+"] 被创建");
}
/**
*<p>Title: run</p>
*<p>Description:JDK线程类自带方法</p>
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public void run() {
this.isRun = true;
while(!isDead){
while(true){
if(!isStop){
if(preConditions())execute();
}else{
break;
}
sleep(256);//缓解CPU压力,即唤醒线程需要至多256ms
}
}
isRun = false;
logger.info("线程:[" + this.getName() +"-"+this.getId()+ "] 消亡");
}
/**
*<p>Title: preConditions</p>
*<p>Description:执行体前置条件</p>
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
protected boolean preConditions(){
return true;
}
/**
*<p>Title: execute</p>
*<p>Description:线程执行体</p>
* @param 设定文件
* @return void 返回类型
* @throws
*/
protected void execute(){
}
/**
*<p>Title: kill</p>
*<p>Description:结束线程</p>
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void kill(){
this.isStop = true;
this.isDead = true;
this.isRun = false;
logger.info("线程:["+this.getName()+"-"+this.getId()+"] 被终止");
}
/**
*<p>Title: halt</p>
*<p>Description:暂停进程,非休眠</p>
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void halt(){
this.isStop = true;
logger.info("线程:["+this.getName()+"-"+this.getId()+"] 被暂停");
}
/**
*<p>Title: reStart</p>
*<p>Description:重新执行线程</p>
* @param 设定文件
* @return void 返回类型
* @throws
*/
public void reStart(){
this.isStop = false;
logger.info("线程:["+this.getName()+"-"+this.getId()+"] 被重新执行");
}
/**
*<p>Title: isRun</p>
*<p>Description:是否处于执行态</p>
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public boolean isRun() {
return isRun;
}
/**
*<p>Title: isSleep</p>
*<p>Description:是否处于休眠态</p>
* @param @return 设定文件
* @return boolean 返回类型
* @throws
*/
public boolean isSleep() {
return isSleep;
}
public boolean isDead(){
return isDead;
}
/**
*<p>Title: sleep</p>
*<p>Description:休眠线程</p>
* @param @param millis
* @param @throws InterruptedException 设定文件
* @return void 返回类型
* @throws
*/
public void sleep(int millis){
isSleep = true;
try {
Thread.sleep(millis);
this.sleepTime += millis;
if(notifyPreConditions())notifyObs();
} catch (InterruptedException e) {
e.printStackTrace();
}
isSleep = false;
}
复制代码
线程启动后,会一直处于运行状态,线程每次执行都会无条件休眠256ms以缓解不必要的实时性带来的巨大CPU消耗.
同时使用模板方法,让子类有更好的扩展延伸性 。
将执行体独立成一个方法
execute
()便于扩展,同时在执行体前加入一个
preConditions
()执行体前置条件,将执行体执行的充分条件独立,避免多余代码运算,提高效率。
作者:
侯宪博
时间:
2012-7-29 02:01
太专业了,为楼主无私奉献的精神呐喊!果断顶起!!!!
作者:
党巾水
时间:
2012-7-29 08:10
收藏了,谢谢楼主
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2