优化Java线程实现类

4 篇文章 0 订阅

多线程编程一方面比较复杂,另一方面运行出错后,难以定位等,所以针对对多线程实现的场景需要更谨慎,多关注编程实现的细节, 以便更好的实现和问题定位。

我们先来看一段实现Thread线程类的代码:

  public class ThreadTest {
      public static void main(String[] args) {
          new Thread() {
              @Override
              public void run() {
                  while (true) {
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      System.out.println(getName() + ", do something...");
                  }
              }
          }.start();
          System.out.println("exit main...");
      }
  }

咋一看好像没什么问题,确实这段程序执行起来是没有什么大问题,但是仔细想一想程序是写给人看的,而且是由人维护的, 有更大的可能是你来实现,其他人来维护的,如果没问题还好,一旦有问题,再回过头来看代码和查找日志,都是个比较头疼的问题。

从代码维护角度来说,这段代码存在以下几个问题(当然不同的人理解不一样,有一些不见得是问题):

  • 未定义变量和匿名实现,不利于对象的回收和利用
  • 未设置为守护线程,主线程已停止,子线程还在后台执行
  • 未定义结束标识,线程循环执时无法在流程上友好地停止循环
  • 未设定明确的线程名,系统将自动分配线程名,然而在一个系统中往往会有很多个线程,如果都是这样,就无法确定哪个线程对应处理流程,特别是通过一些工具进行分析的时候,比如jconsole等
  • 无明确的初始化,启动,结束日志,一旦线程任意环节出现问题,缺少必要的日志,都给问题定位带来困扰。 线程实现定周期执行,使用线程Thread.sleep(long millis),实际线程资源并没有释放,不利于资源利用,比较好的方法定义一个锁对象,通过Object.wait(long millis) 进行资源释放

为解决以上问题,对Thread类做二次开发,具体如下:

public abstract class AbstractCycleThread extends AbstractThread {

      protected static final int STEP_WAITING = Integer.valueOf(1);

      protected static final int STEP_SOMETHING = Integer.valueOf(2);

      protected static final int STEP_NEXT_CONTINUE = Integer.valueOf(3);

      private volatile boolean cycle = true;

      private Object lock = new Object();

      private long waitTime = 0;

      public AbstractCycleThread(String threadName, long waitTime) {
          super(threadName);
          init(waitTime);
      }

      public AbstractCycleThread(long waitTime) {
          super(getFinalThreadName(AbstractCycleThread.class.getSimpleName()));
          init(waitTime);
      }

      private void init(long waitTime) {
          if (waitTime < 0) {
              this.waitTime = 0;
          } else {
              this.waitTime = waitTime;
          }
          info("init cycle thread, waitTime:" + waitTime);
      }

      @Override
      public void run() {
          info("start to run cycle thread:" + getName());
          int nextStep = STEP_WAITING;
          try {
              while (cycle) {
                  nextStep = beforeWaitingThenDoNextStep();
                  if (STEP_WAITING == nextStep) {
                      if (waitTime > 0) {
                          synchronized (lock) {
                              lock.wait(waitTime);
                          }
                      }
                      if (!afterWaitupThenDoSomething()) {
                          continue;
                      }
                  } else if (STEP_NEXT_CONTINUE == nextStep) {
                      continue;
                  }

                  // 执行业务操作
                  doSomething();
              }
          } catch (Exception e) {
              error("run cycle thread error:" + getName(), e);
              afterError();
              return;
          }
          info("finish to run cycle thread:" + getName());
          afterfinish();

      }

      /**
       * 执行lock.wait休眠等待前的处理操作
       * @return 

       *         

       *         {@link #STEP_WAITING} 进入休眠lock.wait等待
       *         

       *         {@link #STEP_NEXT_CONTINUE} 结束当前,进入下一次循环
       *         

       *         {@link #STEP_SOMETHING} 直接进入{@link #doSomething()}操作
       *         

       */
      protected int beforeWaitingThenDoNextStep() {
          // 可自行实现,默认进入等待
          return STEP_WAITING;
      }

      /**
       * 在{@link #beforeWaitingThenDoNextStep} 返回结果为{@link #STEP_WAITING}
       * 后,执行lock.wait休眠等待,等待结束后执行该方法,处理操作,默认不做任何处理,并返回true
       * 
       * @return 是否继续执行{@link #doSomething}操作
       */
      protected boolean afterWaitupThenDoSomething() {
          // 可自行实现,默认不做处理,直接返回下一步
          return true;
      }

      /**
       * 友好关闭线程
       * @see org.slive.thread.AbstractThread#stopFriendly()
       */
      public void stopFriendly() {
          if (!isAlive()) {
              return;
          }
          // 可自行实现
          // 唤醒后,设置循环标识为false
          synchronized (lock) {
              lock.notifyAll();
          }
          cycle = false;
      }
  }

测试:

public class CycleThreadTest {
      public static void main(String[] args) {
          long waitTime = 500;
          // 线程间数据共享
          List data = new ArrayList<>();
          MyCycleThread[] mcts = new MyCycleThread[5];
          for (int index = 0; index < mcts.length; index++) {
              mcts[index] = new MyCycleThread(waitTime, data);
              mcts[index].start();
          }
          
          int d = 1;
          int cycleTime = 0;
          while ((cycleTime++) < 50) {
              try {
                   // 更新数据共享的值
                  data.add(d++);
                  Thread.sleep(2000);
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
          // 优化关闭所有线程
          for (int index = 0; index < mcts.length; index++) {
              mcts[index].stopFriendly();
          }
      }

      static class MyCycleThread extends AbstractCycleThread {
          private List data;

          private List tempData = new ArrayList<>();

          public MyCycleThread(long waitTime, List data) {
              super(getFinalThreadName(MyCycleThread.class.getSimpleName()), waitTime);
              this.data = data;
          }

          @Override
          protected boolean afterWaitupThenDoSomething() {
              synchronized (data) {
                  if (!data.isEmpty()) {
                      // 如果有数据了,才继续后面的doSomething操作
                      tempData.addAll(data);
                      data.clear();
                      return true;
                  } else {
                      return false;
                  }
              }
          }

          @Override
          protected void doSomething() {
              Iterator ite = tempData.iterator();
              while (ite.hasNext()) {
                  System.out.println(System.currentTimeMillis() + " " + getName() + " do something value:" + ite.next());
                  ite.remove();
              }
          }
      }
  }
  

其它:

个人比较建议继承Thread类而不是实现Runnable接口,因为相对来说,Thread可实现的方法更多,更利于控制线程。

关于线程同步,资源共享,线程池等,与此次讨论的“优化Java线程类实现”并不冲突,处在不同的使用层次上,在此不展开讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值