[关闭]
@linux1s1s 2015-05-18T17:26:55.000000Z 字数 1108 阅读 2056

Schedule线程池

Java


这里小结了Schedule线程池在工作中遇到的问题,首先看一下案例。

Case

  1. public class QoSEventTracker
  2. {
  3. ScheduledExecutorService mScheduler = Executors.newScheduledThreadPool(2);
  4. private void appForeground()
  5. {
  6. mScheduler.scheduleWithFixedDelay(new Runnable()
  7. {
  8. @Override
  9. public void run()
  10. {
  11. if (!isStopped)
  12. {
  13. send(MessageType.APP_HB);
  14. }
  15. }
  16. }, 0, sSecondsInterval, TimeUnit.SECONDS);
  17. }
  18. private void appBackground()
  19. {
  20. isStopped = true;
  21. mScheduler.schedule(new Runnable()
  22. {
  23. @Override
  24. public void run()
  25. {
  26. send(MessageType.APP_STOP);
  27. mScheduler.shutdown() ;
  28. }
  29. }, 1, TimeUnit.SECONDS);
  30. }
  31. private void send(MessageType type)
  32. {
  33. if (payLoad != null)
  34. {
  35. QoSHttpManager.request(sQosServerUrl, generateNameValuePair(payLoad));
  36. }
  37. }
  38. }

这里定一下需求,当App压到后台以后,会调用appBackground()方法,而当Ap获得焦点后调用appForeground()方法,这两个方法里面干的事情也比较统一,就是向Http发送一条请求数据。
基于上面的需求,请问上面的代码有问题吗?

Analytics

如果我们仅仅从上面的需求看代码,我们会得出没有问题的结论,可是事实上的确如此吗?
不妨来分析一下上面的代码:

上面的代码起码有三个线程在做事情,分别是主线程,Schedule线程,Http线程。当主线程开启一个分支进入Schedule线程,这个时候如果发送网络请求就会在Schedule线程中再开启一个分支Http线程,此时三个线程都在运行。这时我们定位到30行和31行,请问看出来问题了吗?
对了,就是这里出了问题,啥问题?线程同步的问题。Http线程请求不一定发出去,线程池就shutdown()了, 那该怎么办?去掉这行代码可以吗?
如果去掉这行代码,那么压到后台以后isStopped = true被置为true以后,虽然线程池还在,但是run方法里面永远不会执行任何代码,这样也就不会做任何事情了。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注