版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/errizh/article/details/79702571
背景:项目中用Jmeter模拟上万个Tcp client,每一个client要定时给Server发送心跳。
在Java中要定时执行一个任务,有很多童鞋自然会想到用Timer,但是Timer如果使用不当,会造成以下问题:
1.每new一个Timer会启动一个线程,如果使用在循环或者递归当中,很容易造成JVM报如下错误:
java.lang.OutOfMemoryError: unable to create new native thread
这个时候机器上的内存并没有耗尽,JVM有一定的保护机制,具体可以参见:
https://www.cnblogs.com/loveyakamoz/archive/2011/08/19/2145244.html
2.Timer中执行的任务,如果有异常抛出,timer就会终止,后续的任务不会再执行,推荐使用ScheduledExecutorService。
阿里推荐的编码规约中这样写道:
多线程并行处理定时任务时,Timer运行多个TimeTask时,只要其中之一没有捕获抛出的异常,其它任务便会自动终止运行,使用ScheduledExecutorService则没有这个问题。 //org.apache.commons.lang3.concurrent.BasicThreadFactory ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(1, new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d").daemon(true).build()); executorService.scheduleAtFixedRate(new Runnable() { @Override public void run() { //do something } },initialDelay,period, TimeUnit.HOURS); |