怎么让手机在固易语言 指定时间运行段自动运行指定任务?

他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)java Timer(定时调用、实现固定时间执行) - WhyWin - 博客园
随笔 - 148, 文章 - 0, 评论 - 331, 引用 - 0
  最近需要用到定时调用的功能。可以通过java的Timer类来进行定时调用,下面是有关Timer的一些相关知识。
  其实就Timer来讲就是一个调度器,而TimerTask呢只是一个实现了run方法的一个类,而具体的TimerTask需要由你自己来实现,例如这样:
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
System.out.println("11232");
}, 200000 , 1000);
  这里直接实现一个TimerTask(当然,你可以实现多个TimerTask,多个TimerTask可以被一个Timer会被分配到多个 Timer中被调度,后面会说到Timer的实现机制就是说内部的调度机制),然后编写run方法,20s后开始执行,每秒执行一次,当然你通过一个 timer对象来操作多个timerTask,其实timerTask本身没什么意义,只是和timer集合操作的一个对象,实现它就必然有对应的run 方法,以被调用,他甚至于根本不需要实现Runnable,因为这样往往混淆视听了,为什么呢?也是本文要说的重点。
  在说到timer的原理时,我们先看看Timer里面的一些常见方法:
1、这个方法是调度一个task,经过delay(ms)后开始进行调度,仅仅调度一次。
public void schedule(TimerTask task, long delay)
2、在指定的时间点time上调度一次。
public void schedule(TimerTask task, Date time)
3、这个方法是调度一个task,在delay(ms)后开始调度,每次调度完后,最少等待period(ms)后才开始调度。
public void schedule(TimerTask task, long delay, long period)
4、和上一个方法类似,唯一的区别就是传入的第二个参数为第一次调度的时间。
public void schedule(TimerTask task, Date firstTime, long period)
5、调度一个task,在delay(ms)后开始调度,然后每经过period(ms)再次调度,貌似和方法:schedule是一样的,其实不然,后面你会根据源码看到,schedule在计算下一次执行的时间的时候,是通过当前时间(在任务执行前得到) + 时间片,而scheduleAtFixedRate方法是通过当前需要执行的时间(也就是计算出现在应该执行的时间)+ 时间片,前者是运行的实际时间,而后者是理论时间点,例如:schedule时间片是5s,那么理论上会在5、10、15、20这些时间片被调度,但是如果由于某些CPU征用导致未被调度,假如等到第8s才被第一次调度,那么schedule方法计算出来的下一次时间应该是第13s而不是第10s,这样有可能下次就越到20s后而被少调度一次或多次,而scheduleAtFixedRate方法就是每次理论计算出下一次需要调度的时间用以排序,若第8s被调度,那么计算出应该是第10s,所以它距离当前时间是2s,那么再调度队列排序中,会被优先调度,那么就尽量减少漏掉调度的情况。
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
6、方法同上,唯一的区别就是第一次调度时间设置为一个Date时间,而不是当前时间的一个时间片,我们在源码中会详细说明这些内容。
public void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)
首先看Timer的构造方法有几种:
构造方法1:无参构造方法,简单通过Tiemer为前缀构造一个线程名称:
public Timer() {
this("Timer-" + serialNumber());
&  创建的线程不为主线程,则主线程结束后,timer自动结束,而无需使用cancel来完成对timer的结束。
构造方法2:传入了是否为后台线程,后台线程当且仅当进程结束时,自动注销掉。
public Timer(boolean isDaemon) {
this("Timer-" + serialNumber(), isDaemon);
&  另外两个构造方法负责传入名称和将timer启动:
public Timer(String name, boolean isDaemon) {
thread.setName(name);
thread.setDaemon(isDaemon);
thread.start();
&  这里有一个thread,这个thread很明显是一个线程,被包装在了Timer类中,我们看下这个thread的定义是:
private TimerThread thread = new TimerThread(queue);
  而定义TimerThread部分的是:
而定义TimerThread部分的是:
&  看到这里知道了,Timer内部包装了一个线程,用来做独立于外部线程的调度,而TimerThread是一个default类型的,默认情况下是引用不到的,是被Timer自己所使用的。
  接下来看下有那些属性
  除了上面提到的thread,还有一个很重要的属性是:
private TaskQueue queue = new TaskQueue();
&  看名字就知道是一个队列,队列里面可以先猜猜看是什么,那么大概应该是我要调度的任务吧,先记录下了,接下来继续向下看:
  里面还有一个属性是:threadReaper, 它是Object类型,只是重写了finalize方法而已,是为了垃圾回收的时候,将相应的信息回收掉,做GC的回补,也就是当timer线程由于某种 原因死掉了,而未被cancel,里面的队列中的信息需要清空掉,不过我们通常是不会考虑这个方法的,所以知道java写这个方法是干什么的就行了。
  接下来看调度方法的实现:
  对于上面6个调度方法,我们不做一一列举,为什么等下你就知道了:
  来看下方法:
public void schedule(TimerTask task, long delay)
&  的源码如下:
1 public void schedule(TimerTask task, long delay) {
if (delay & 0)
throw new IllegalArgumentException("Negative delay.");
sched(task, System.currentTimeMillis()+delay, 0);
&  这里调用了另一个方法,将task传入,第一个参数传入System.currentTimeMillis()+delay可见为第一次需要执行的时间的 时间点了(如果传入Date,就是对象.getTime()即可,所以传入Date的几个方法就不用多说了),而第三个参数传入了0,这里可以猜下要么是 时间片,要么是次数啥的,不过等会就知道是什么了;另外关于方法:sched的内容我们不着急去看他,先看下重载的方法中是如何做的
  再看看方法:
public void schedule(TimerTask task, long delay,long period)
&  源码为:
public void schedule(TimerTask task, long delay, long period) {
if (delay & 0)
throw new IllegalArgumentException("Negative delay.");
if (period &= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, -period);
&  看来也调用了方法sched来完成调度,和上面的方法唯一的调度时候的区别是增加了传入的period,而第一个传入的是0,所以确定这个参数为时间片, 而不是次数,注意这个里的period加了一个负数,也就是取反,也就是我们开始传入1000,在调用sched的时候会变成-1000,其实最终阅读完 源码后你会发现这个算是老外对于一种数字的理解,而并非有什么特殊的意义,所以阅读源码的时候也有这些困难所在。
  最后再看个方法是:
public void scheduleAtFixedRate(TimerTasktask,long delay,long period)
&  源码为:
public void scheduleAtFixedRate(TimerTask task, long delay, long period) {
if (delay & 0)
throw new IllegalArgumentException("Negative delay.");
if (period &= 0)
throw new IllegalArgumentException("Non-positive period.");
sched(task, System.currentTimeMillis()+delay, period);
&  唯一的区别就是在period没有取反,其实你最终阅读完源码,上面的取反没有什么特殊的意义,老外不想增加一个参数来表示 scheduleAtFixedRate,而scheduleAtFixedRate和schedule的大部分逻辑代码一致,因此用了参数的范围来作为 区分方法,也就是当你传入的参数不是正数的时候,你调用schedule方法正好是得到scheduleAtFixedRate的功能,而调用 scheduleAtFixedRate方法的时候得到的正好是schedule方法的功能,呵呵,这些讨论没什么意义,讨论实质和重点:
&  来看sched方法的实现体:
private void sched(TimerTask task, long time, long period) {
if (time & 0)
throw new IllegalArgumentException("Illegal execution time.");
synchronized(queue) {
if (!thread.newTasksMayBeScheduled)
throw new IllegalStateException("Timer already cancelled.");
synchronized(task.lock) {
if (task.state != TimerTask.VIRGIN)
throw new IllegalStateException(
"Task already scheduled or cancelled");
task.nextExecutionTime =
task.period =
task.state = TimerTask.SCHEDULED;
queue.add(task);
if (queue.getMin() == task)
queue.notify();
&  queue为一个队列,我们先不看他数据结构,看到他在做这个操作的时候,发生了同步,所以在timer级别,这个是线程安全的,最后将task相关的参数赋值,主要包含nextExecutionTime(下一次执行时间),period(时间片),state(状态),然后将它放入queue队列中,做一次notify操作,为什么要做notify操作呢?看了后面的代码你就知道了。
  简言之,这里就是讲task放入队列queue的过程,此时,你可能对queue的结构有些兴趣,那么我们先来看看queue属性的结构TaskQueue:
class TaskQueue {
private TimerTask[] queue = new TimerTask[128];
private int size = 0;
&  可见,TaskQueue的结构很简单,为一个数组,加一个size,有点像ArrayList,是不是长度就128呢,当然不 是,ArrayList可以扩容,它可以,只是会造成内存拷贝而已,所以一个Timer来讲,只要内部的task个数不超过128是不会造成扩容的;内部 提供了add(TimerTask)、size()、getMin()、get(int)、removeMin()、quickRemove(int)、 rescheduleMin(long newTime)、isEmpty()、clear()、fixUp()、fixDown()、heapify();
实践部分:
1、通过继承TimerTask的方式实现
  必须重写run方法.
public class MyTask extends TimerTask
public void run()
SimpleDateFormat sdf = null;
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
System.out.println("当前时间:" + sdf.format(new Date()));
public class TestTask
public static void main(String[] args)
Timer t = new Timer(); // 建立Timer对象
MyTask task = new MyTask(); //定义任务
t.schedule(task, );//设置任务的执行,1秒后开始,每2秒执行一次
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MINUTE, 30);
t.schedule(task, cal.getTime() , 2000);
2、通过匿名内部类实现
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("abc");
}, 1000 , 1000);
  &致谢:感谢您的耐心阅读!在Java中如何设置一个定时任务,在每天的一个时间点自动执行一个特定的程序?具体代码怎么写?代码全点_百度知道
该问题可能描述不清,建议你
在Java中如何设置一个定时任务,在每天的一个时间点自动执行一个特定的程序?具体代码怎么写?代码全点
我有更好的答案
org.dtd" target="_blank">mainJob& class=&&&0 15 10 * * ? *& 每天上午10:15触发 &&
&ref bean=&quot.property&0 15 10 ? * *& 每天上午10:15触发 &!-- 0 0 10,14;0 15 10 * * ? 2005&property&gt:15触发 &0 15 10 ;/&&#47?&lt:59期间的每1分钟触发 & 每月15日上午10:15触发 &quot:15触发 &0 * 14 * * ?& 在每天下午2点到下午2;定时执行类里面的哪个方法
&bean id=&&/将你的类添加到定时器当中
&/value&cronExpression& 在每天下午2点到下午2:55期间的每5分钟触发 &0 0/5 14;30 9-17 * * ?
朝九晚五工作时间内每半小时0 0 12 ? * WED 表示每个星期三中午12点 &0 0 12 * * ?& 每天中午12点触发 & encoding=&timeTrigger& class=&&gt?&quot.MethodInvokingJobDetailFactoryBean& 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 &0 0-5 14 * * ?& 在每天下午2点到下午2;/DTD BEAN/org?&quot?&beans&
&bean id=&mainTask& class=&5 14 * * ; 每年三月的星期三的下午2;?xml version=&1.0&quot.scheduling.quartz? 3 WED&quot.CronTriggerBean&&
&lt? * 6L& 每月的最后一个星期五上午10:15触发 &&mainTask&
&value& // class=&org.springframework. 2005年的每天上午10;bean&jobDetail&&
&lt:15触发 &0 15 10 ;/&
&&#47? 每天上午10点,下午2点;value&0 0/5 * * * ;/property&&/0 15 10 * * ?& 每天上午10:15触发 &quot:10和2:44触发 &quot.MainTask&quot?&!DOCTYPE beans PUBLIC &property name=&0 15 10 ? * 6L && 每月的第三个星期五上午10:15触发 上面这个是quartz的语法 定时单位 --&/property&&/0 15 10 L * ?& 每月最后一日的上午10;/&
//&lt.0 0&#47.&property name=&
&/list&gt,18 * * ;0 15 10 ? * MON-FRI& 周一至周五的上午10:15触发 &quot,16 * * ? * 6#3&
&lt.-//bean&&bean id=&sfb&bean id=&/SPRING/ //下面这个类就是我在XML中引入的类package net.import java.io.IOEimport java.text.SimpleDateFimport java.util.Dpublic class MainTask {
public void execute() throws IOException
SimpleDateFormat dateFormat = new SimpleDateFormat(&yyyy-MM-dd HH:mm:ss&);
System.out.println(&do my job&+dateFormat.format(new Date()));
Runtime.getRuntime().exec(&cmd /c start E:/mbl/BusinessOffice/MoneDB/bin/bakup.bat&);
}}然后在web.xml中把这个TimeConfig.xml添加进去作为监听系统启动的时候自动就监听这个事件 &?xml version=&1.0& encoding=&UTF-8&?&&web-app version=&2.5&
xmlns:xsi=&&
xsi:schemaLocation=&
/web-app_2_5.xsd&& &context-param&
&param-name&
contextConfigLocation
&/param-name&
&param-value&
/WEB-INF/TimerConfig.xml
&/param-value& &/context-param& &listener&
&listener-class&
org.springframework.web.context.ContextLoaderListener
&/listener-class& &/listener&
&welcome-file-list&
&welcome-file&index.jsp&/welcome-file&
&/welcome-file-list&&/web-app&这个是quartz spring的定时机制
请仔细的看看 如果可以请给分哦.quartz.SchedulerFactoryBean&&
&property name=&triggers&&
&ref local=&timeTrigger&
&execute&/&targetObject&quot:05期间的每1分钟触发 &0 15 10 15 * ;/EN&&<a href="http://www.springframework.org/dtd/spring-UTF-8&;property name=&quot.org/dtd/spring-beans.dtd&quot,4点0 0//beans&0 10,44 14 ://jar类
&lt.scheduling.ref bean=&mainJob&你要执行的任务类
//bean& 2002年至2005年的每月的最后一个星期五上午10.xml 名字可以自己定义&ltQuartz定时机制首先导入jar包到程序内
quartz-all-1.6.0.jar然后创建一个XMLTimeC/property&
&property name=&targetMethod&&
&value&定时的语法
采纳率:42%
while(true){里面写时间的判断}
1条折叠回答
为您推荐:
其他类似问题
java的相关知识
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 指定时间运行程序 的文章

 

随机推荐