java timer异常_JAVA Timer的缺陷以及解决办法
1、Timer管理延时任务的缺陷
a、以前在项目中也经常使用定时器,比如每隔一段时间清理项目中的一些垃圾文件,每个一段时间进行数据清洗;然而Timer是存在一些缺陷的,因为Timer在执行定时任务时只会创建一个线程,所以如果存在多个任务,且任务时间过长,超过了两个任务的间隔时间,会发生一些缺陷:下面看例子:
Timer的源码:
public class Timer {
/**
* The timer task queue. This data structure is shared with the timer
* thread. The timer produces tasks, via its various schedule calls,
* and the timer thread consumes, executing timer tasks as appropriate,
* and removing them from the queue when they're obsolete.
*/
private TaskQueue queue = new TaskQueue();
/**
* The timer thread.
*/
private TimerThread thread = new TimerThread(queue);
TimerThread是Thread的子类,可以看出内部只有一个线程。下面看个例子:
package com.zhy.concurrency.timer;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest
{
private static long start;
public static void main(String[] args) throws Exception
{
TimerTask task1 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task1 invoked ! "
+ (System.currentTimeMillis() - start));
try
{
Thread.sleep(3000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
};
TimerTask task2 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task2 invoked ! "
+ (System.currentTimeMillis() - start));
}
};
Timer timer = new Timer();
start = System.currentTimeMillis();
timer.schedule(task1, 1000);
timer.schedule(task2, 3000);
}
}
定义了两个任务,预计是第一个任务1s后执行,第二个任务3s后执行,但是看运行结果:
task1 invoked ! 1000
task2 invoked ! 4000
task2实际上是4后才执行,正因为Timer内部是一个线程,而任务1所需的时间超过了两个任务间的间隔导致。下面使用ScheduledThreadPool解决这个问题:
package com.zhy.concurrency.timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExecutorTest
{
private static long start;
public static void main(String[] args)
{
/**
* 使用工厂方法初始化一个ScheduledThreadPool
*/
ScheduledExecutorService newScheduledThreadPool = Executors
.newScheduledThreadPool(2);
TimerTask task1 = new TimerTask()
{
@Override
public void run()
{
try
{
System.out.println("task1 invoked ! "
+ (System.currentTimeMillis() - start));
Thread.sleep(3000);
} catch (Exception e)
{
e.printStackTrace();
}
}
};
TimerTask task2 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task2 invoked ! "
+ (System.currentTimeMillis() - start));
}
};
start = System.currentTimeMillis();
newScheduledThreadPool.schedule(task1, 1000, TimeUnit.MILLISECONDS);
newScheduledThreadPool.schedule(task2, 3000, TimeUnit.MILLISECONDS);
}
}
输出结果:
task1 invoked ! 1001
task2 invoked ! 3001
符合我们的预期结果。因为ScheduledThreadPool内部是个线程池,所以可以支持多个任务并发执行。
2、Timer当任务抛出异常时的缺陷
如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行:
package com.zhy.concurrency.timer;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class ScheduledThreadPoolDemo01
{
public static void main(String[] args) throws InterruptedException
{
final TimerTask task1 = new TimerTask()
{
@Override
public void run()
{
throw new RuntimeException();
}
};
final TimerTask task2 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task2 invoked!");
}
};
Timer timer = new Timer();
timer.schedule(task1, 100);
timer.scheduleAtFixedRate(task2, new Date(), 1000);
}
}
上面有两个任务,任务1抛出一个运行时的异常,任务2周期性的执行某个操作,输出结果:
task2 invoked!
Exception in thread "Timer-0" java.lang.RuntimeException
at com.zhy.concurrency.timer.ScheduledThreadPoolDemo01$1.run(ScheduledThreadPoolDemo01.java:24)
at java.util.TimerThread.mainLoop(Timer.java:512)
at java.util.TimerThread.run(Timer.java:462)
由于任务1的一次,任务2也停止运行了。。。下面使用ScheduledExecutorService解决这个问题:
package com.zhy.concurrency.timer;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolDemo01
{
public static void main(String[] args) throws InterruptedException
{
final TimerTask task1 = new TimerTask()
{
@Override
public void run()
{
throw new RuntimeException();
}
};
final TimerTask task2 = new TimerTask()
{
@Override
public void run()
{
System.out.println("task2 invoked!");
}
};
ScheduledExecutorService pool = Executors.newScheduledThreadPool(1);
pool.schedule(task1, 100, TimeUnit.MILLISECONDS);
pool.scheduleAtFixedRate(task2, 0 , 1000, TimeUnit.MILLISECONDS);
}
}
代码基本一致,但是ScheduledExecutorService可以保证,task1出现异常时,不影响task2的运行:
task2 invoked!
task2 invoked!
task2 invoked!
task2 invoked!
task2 invoked!...
3、Timer执行周期任务时依赖系统时间
Timer执行周期任务时依赖系统时间,如果当前系统时间发生变化会出现一些执行上的变化,ScheduledExecutorService基于时间的延迟,不会由于系统时间的改变发生执行变化。
上述,基本说明了在以后的开发中尽可能使用ScheduledExecutorService(JDK1.5以后)替代Timer。
java timer异常_JAVA Timer的缺陷以及解决办法相关推荐
- java 线程安全问题_java线程安全问题原因及解决办法
1.为什么会出现线程安全问题 计算机系统资源分配的单位为进程,同一个进程中允许多个线程并发执行,并且多个线程会共享进程范围内的资源:例如内存地址.当多个线程并发访问同一个内存地址并且内存地址保存的值是 ...
- java jce配置_java JCE 不限密钥长度解决办法
()转自http://opensourceforgeeks.blogspot.com/2014/09/how-to-install-java-cryptography.html 另外,在StackOv ...
- java 到异常_java编程中遇到的异常以及异常的一些处理
n 异常的概念 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户? 比如除法运算.读写文件操作,都可能 ...
- Win7下运行小雨伞tinyumbrella-5/6异常:Exception in thread AWT-EventQueue-0解决办法
[转]Win7下运行小雨伞tinyumbrella-5/6异常:Exception in thread "AWT-EventQueue-0"解决办法 来自威锋网 原文链接:http ...
- java getparameter 乱码,request.getParameter()取值乱码解决办法
当前位置:我的异常网» Java Web开发 » request.getParameter()取值乱码解决办法 request.getParameter()取值乱码解决办法 www.myexcepti ...
- com/opensymphony/xwork2/spring/SpringObjectFactory.java:220:-1问题出现的原因及解决办法
转自:https://blog.csdn.net/shinchan_/article/details/37818927 com/opensymphony/xwork2/spring/SpringObj ...
- ANDROID开发java.lang.NoClassDefFoundError: com.baidu.location.LocationClient的解决办法
ANDROID开发java.lang.NoClassDefFoundError: com.baidu.location.LocationClient的解决办法 java.lang.NoClassDe ...
- ios阴阳是不显示服务器,阴阳师IOS登录异常怎么办 苹果不能正常登录解决办法...
在11月11日阴阳师新版本更新后,许多苹果IOS服务器的玩家反馈登录异常,经常登录不进游戏,对此4399挽歌为大家带来具体解决方法,一起来看看阴阳师IOS登录异常怎么办 苹果不能正常登录解决办法吧! ...
- java: JDK isn‘t specified for module ‘maven-junit41‘解决办法
java: JDK isn't specified for module 'maven-junit41'解决办法. 在单元测试中出现错误:java: JDK isn't specified for m ...
- Caused by: java.lang.ClassNotFoundException: org.apache.log4j.Priority 的解决办法
问题概述: 使用 Spring Boot-2.0.3 进行项目开发,在配置 Druid 数据监控时,遇到缺包的问题,测试连接操作时报错,导致测试一直无法通过,部分信息如下: Caused by: ja ...
最新文章
- 函数重载和覆盖(重写)的区别
- 【问链财经-区块链基础知识系列】 第二十七课 区块链与分布式账本的异同
- 【已解决】tomcat启动不成功(点击startup.bat闪退)的解决办法
- 音视频技术开发周刊 | 154
- 如何解析json字符串及返回json数据到前端
- 11-11 又是一年光棍节!
- 使用未初始化的内存是什么意思_他们都说JVM能实际使用的内存比-Xmx指定的少?这是为什么呢...
- Kotlin实战【四】迭代事物:while和for
- 如何在js中实现html语言,如何使用脚本标签将JavaScript插入HTML
- java win10_java下载64位win10-javawin10 64位下载8.0.1210.13官方版-西西软件下载
- PaddleOCR二次全流程——2.使用StyleText合成图片
- jq ui.dialog.js简介
- python数据分析之朴素贝叶斯实践
- AWD竞赛脚本大全——从攻击到防御
- 2022年最新文本生成图像研究 开源工作速览(Papers with code)
- web应用基本框架图
- 多媒体基础学习笔记:MPEG-7
- 因测试和登录软件微信被封,淘客必须注意,微信封号原则是什么?
- 中国首届DFMA降本设计峰会
- 【ES8系列】String 补白、格式化
热门文章
- cortex M3/4 内部总线
- 打印端口用计算机名,如何设置打印机端口,教您设置电脑打印机端口
- python什么情况下要加eval_python 为什么说eval要慎用?使用eval 带来的潜在风险?什么情况下使用eval?...
- vue实现农历日期选择器
- 计算机自动关机原理,电脑自动关机什么原因 电脑自动关机是怎么回事
- 学计算机投影仪定义,一种计算机信息技术教学用投影仪的制作方法
- CentOS 7.5 安装MySQL教程
- Java:spring Value注解用法详解
- 【Java算法学习】鸡兔同笼问题
- 阿里云云原生数据湖体系全解读——数据湖构建 数据导入