@linux1s1s
2015-05-18T17:26:55.000000Z
字数 1108
阅读 2056
Java
这里小结了Schedule线程池在工作中遇到的问题,首先看一下案例。
public class QoSEventTracker
{
ScheduledExecutorService mScheduler = Executors.newScheduledThreadPool(2);
private void appForeground()
{
mScheduler.scheduleWithFixedDelay(new Runnable()
{
@Override
public void run()
{
if (!isStopped)
{
send(MessageType.APP_HB);
}
}
}, 0, sSecondsInterval, TimeUnit.SECONDS);
}
private void appBackground()
{
isStopped = true;
mScheduler.schedule(new Runnable()
{
@Override
public void run()
{
send(MessageType.APP_STOP);
mScheduler.shutdown() ;
}
}, 1, TimeUnit.SECONDS);
}
private void send(MessageType type)
{
if (payLoad != null)
{
QoSHttpManager.request(sQosServerUrl, generateNameValuePair(payLoad));
}
}
}
这里定一下需求,当App压到后台以后,会调用appBackground()
方法,而当Ap获得焦点后调用appForeground()
方法,这两个方法里面干的事情也比较统一,就是向Http发送一条请求数据。
基于上面的需求,请问上面的代码有问题吗?
如果我们仅仅从上面的需求看代码,我们会得出没有问题的结论,可是事实上的确如此吗?
不妨来分析一下上面的代码:
上面的代码起码有三个线程在做事情,分别是主线程,Schedule线程,Http线程。当主线程开启一个分支进入Schedule线程,这个时候如果发送网络请求就会在Schedule线程中再开启一个分支Http线程,此时三个线程都在运行。这时我们定位到30行和31行,请问看出来问题了吗?
对了,就是这里出了问题,啥问题?线程同步的问题。Http线程请求不一定发出去,线程池就shutdown()
了, 那该怎么办?去掉这行代码可以吗?
如果去掉这行代码,那么压到后台以后isStopped = true
被置为true以后,虽然线程池还在,但是run方法里面永远不会执行任何代码,这样也就不会做任何事情了。