A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

马进

初级黑马

  • 黑马币:0

  • 帖子:7

  • 精华:0

本帖最后由 马进 于 2012-7-29 00:56 编辑

大家都知道线程执行体run()方法一旦执行完毕,线程就会退出,同时JVM会释放掉线程占用的所有资源,让线程呈现出一中只读状态。在处理数据来源不确定,处理时间不确定的场景下就无法保证线程的合理运作。由于JDK提供的线程暂停是非线程安全的,可能造成死锁,已经被不推荐使用,这样我们就需要一种机制对线程做暂停,重新启动,停止等操作。以下是我写的一段代码,从工作经验中所得。
  1. public class BaseThread extends Thread{
  2.         private final static Logger logger = Logger.getLogger(BaseThread.class);

  3.         /**
  4.          * isDead:是否杀死线程
  5.          */
  6.         private boolean isDead = false;
  7.         
  8.         /**
  9.          * isStop:是否停止
  10.          */
  11.         private boolean isStop = false;
  12.         
  13.         /**
  14.          * isRun:是否已开始执行
  15.          */
  16.         private boolean isRun = false;
  17.         
  18.         /**
  19.          * isWait:是否处于等待
  20.          */
  21.         private boolean isSleep = false;
  22.         
  23.         public BaseThread() {
  24.                 super();
  25.                 this.setDaemon(false);//设置为非守护线程
  26.                 logger.info("线程:["+this.getId()+"] 被创建");
  27.         }
  28.         
  29.         public BaseThread(String threadName) {
  30.                 super(threadName);
  31.                 this.setDaemon(false);//设置为非守护线程
  32.                 logger.info("线程:["+threadName+"-"+this.getId()+"] 被创建");
  33.         }

  34.         /**
  35.          *<p>Title: run</p>
  36.          *<p>Description:JDK线程类自带方法</p>
  37.          * @param @return 设定文件
  38.          * @return  boolean 返回类型
  39.          * @throws
  40.         */
  41.         public void run() {
  42.                 this.isRun = true;
  43.                 while(!isDead){
  44.                         while(true){
  45.                                 if(!isStop){
  46.                                         if(preConditions())execute();
  47.                                 }else{
  48.                                         break;
  49.                                 }
  50.                                 sleep(256);//缓解CPU压力,即唤醒线程需要至多256ms
  51.                         }
  52.                 }
  53.                 isRun = false;
  54.                 logger.info("线程:[" + this.getName() +"-"+this.getId()+ "] 消亡");
  55.         }
  56.         
  57.         /**
  58.          *<p>Title: preConditions</p>
  59.          *<p>Description:执行体前置条件</p>
  60.          * @param @return 设定文件
  61.          * @return  boolean 返回类型
  62.          * @throws
  63.         */
  64.         protected boolean preConditions(){
  65.                 return true;
  66.         }
  67.         
  68.         /**
  69.          *<p>Title: execute</p>
  70.          *<p>Description:线程执行体</p>
  71.          * @param  设定文件
  72.          * @return  void 返回类型
  73.          * @throws
  74.         */
  75.         protected void execute(){
  76.                         
  77.         }

  78.         /**
  79.          *<p>Title: kill</p>
  80.          *<p>Description:结束线程</p>
  81.          * @param  设定文件
  82.          * @return  void 返回类型
  83.          * @throws
  84.         */
  85.         public void kill(){
  86.                 this.isStop = true;
  87.                 this.isDead = true;
  88.                 this.isRun = false;
  89.                 logger.info("线程:["+this.getName()+"-"+this.getId()+"] 被终止");
  90.         }
  91.         
  92.         /**
  93.          *<p>Title: halt</p>
  94.          *<p>Description:暂停进程,非休眠</p>
  95.          * @param  设定文件
  96.          * @return  void 返回类型
  97.          * @throws
  98.         */
  99.         public void halt(){
  100.                 this.isStop = true;
  101.                 logger.info("线程:["+this.getName()+"-"+this.getId()+"] 被暂停");
  102.         }
  103.         
  104.         /**
  105.          *<p>Title: reStart</p>
  106.          *<p>Description:重新执行线程</p>
  107.          * @param  设定文件
  108.          * @return  void 返回类型
  109.          * @throws
  110.         */
  111.         public void reStart(){
  112.                 this.isStop = false;
  113.                 logger.info("线程:["+this.getName()+"-"+this.getId()+"] 被重新执行");
  114.         }

  115.         /**
  116.          *<p>Title: isRun</p>
  117.          *<p>Description:是否处于执行态</p>
  118.          * @param @return 设定文件
  119.          * @return  boolean 返回类型
  120.          * @throws
  121.         */
  122.         public boolean isRun() {
  123.                 return isRun;
  124.         }

  125.         /**
  126.          *<p>Title: isSleep</p>
  127.          *<p>Description:是否处于休眠态</p>
  128.          * @param @return 设定文件
  129.          * @return  boolean 返回类型
  130.          * @throws
  131.         */
  132.         public boolean isSleep() {
  133.                 return isSleep;
  134.         }
  135.         
  136.         public boolean isDead(){
  137.                 return isDead;
  138.         }
  139.         
  140.         /**
  141.          *<p>Title: sleep</p>
  142.          *<p>Description:休眠线程</p>
  143.          * @param @param millis
  144.          * @param @throws InterruptedException 设定文件
  145.          * @return  void 返回类型
  146.          * @throws
  147.         */
  148.         public void sleep(int millis){
  149.                 isSleep = true;
  150.                 try {
  151.                         Thread.sleep(millis);
  152.                         this.sleepTime += millis;
  153.                         if(notifyPreConditions())notifyObs();
  154.                 } catch (InterruptedException e) {
  155.                         e.printStackTrace();
  156.                 }
  157.                 isSleep = false;
  158.         }
复制代码
线程启动后,会一直处于运行状态,线程每次执行都会无条件休眠256ms以缓解不必要的实时性带来的巨大CPU消耗.
同时使用模板方法,让子类有更好的扩展延伸性 。
将执行体独立成一个方法execute ()便于扩展,同时在执行体前加入一个preConditions ()执行体前置条件,将执行体执行的充分条件独立,避免多余代码运算,提高效率。


评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

2 个回复

倒序浏览
太专业了,为楼主无私奉献的精神呐喊!果断顶起!!!!
回复 使用道具 举报
收藏了,谢谢楼主
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马