论坛首页 Java版

愚蠢的java.util.TimerTask [愚蠢的java.util.*系列之三]

浏览 15251 次
该帖已经被评为精华帖
作者 正文
最后更新时间:2004-07-29
200x年x月x日

到了办公室, 屁股刚刚接触到偶可爱椅子的脸蛋, 老大从办公室就探出他的脸蛋来了: 狗蛋, 进来一下!
偶看其桃花满面的样子, 想想应该是好事, 赶紧屁颠屁颠地进去了.
老大: 我们那个2.0版本的SIHT系统, 在客户那边做测试的这段时间, 他们反映很好.
偶: 嘿嘿, 那是不是大家伙可以休假一段时间了?
老大: 嗯, 把这些反馈解决掉, 我们就放假吧.
老大递过来一叠卡片......, 我#@$%^!@#&

回到坐位, 按照惯例, 大叫一声: 弟兄们, 来分糖果了.
合理的, 容易做的要求拣出来, 各自认领回家先写个plan, 剩下的东东等明天早上开会再唐僧唐僧.

呼, 好累啊, 工作也分配完了, 那么偶今天就休息吧. (各位看官看到此处, 一定会想, 哪里有这么好混的公司呀) 唉, 现实总是残酷的, 为了休假早日到来, 不得不咬紧牙关, 先看看剩下的卡片上都写了些什么吧.

丫丫呸, 看看这张卡片写的: 为什么系统的备份每次都需要人工去打个backup的命令, 难道不能设置一个定时, 让它自动跑吗?
kao, 竟然遇到一个知道电脑有定时功能的用户, 有水平.

定时......, 从来没有做过, 自己写一个线程让它自己去跑? 不会这么愚蠢吧, 这次是既没看过猪跑步, 也没吃过猪肉, 不过没有关系, 祭出偶的宝贝------google, 输入java schedule example, 扫了一眼搜索结果, 原来有这么多人看过猪跑步呀: java.util.Timer and java.util.TimerTask.

先扫描了一下example, 嗯, 代码很简单的说:
[code:1]
    Timer timer = new Timer();
   
    timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                // Task here ...
            }
        }, delay, period);
[/code:1]

看看偶们原来的代码, 采用Command方式的:
[code:1]
    public class BackupCommand extends AbstractCommand {
        public String execute(){
            getBackupDevice().doBackup();
            return SUCCESS;
        }
    }
[/code:1]

心情大好, 看来10分钟就可以搞定了, 先试试看:
[code:1]
    public class ScheduledBackupCommand extends BackupCommand implements TimerTask {
        public void run() {
            super.execute();
        }
    }
[/code:1]

编译一下先, 发现一个错误, TimerTask不是一个接口......
tnnd, 前面扫瞄代码的时候怎么没有注意到这个问题呢, 偶的ScheduledBackupCommand还想继续用偶们的Command接口呢, 那只好改写吧:
[code:1]
    public class ScheduledBackupCommand extends TimerTask implements Command {
        private BackupCommand backupCommand;
       
        public ScheduledBackupCommand(BackupCommand command){
            this.backupCommand = command;
        }
       
        public void run() {
            backupCommand.execute();
        }
       
        public String execute() {
            return backupCommand.execute();
        }
    }
[/code:1]
虽然代码难看了许多, 但是毕竟是写完了, 加个测试代码, 通过, yeah, 收工.

看看新闻, 在论坛上灌灌水, 收发垃圾email...... 慢着, 象偶这样一个上进青年怎么能就这样堕落掉呢? 找点有意义的事情做吧, 去看看TimerTask有什么鬼原因用Abstract Class吧.

先看Timer吧, 原来是一个线程队列, 细节看不懂, 略过.
那么看看TimerTask的实例方法, 有: public boolean cancel() 和 public long scheduledExecutionTime(), 但是前面看到的Timer代码好像没调用到这2个方法呀, 回头再仔细瞅瞅, tnnd, 果真如此!!!!

鄙视一万次呀, 一万次. 难道SUN不知道Java只能extends一个么???? 做这么基础的lib, 竟然为了2个垃圾方法, 而不用iterface???? 为什么TimerTask不设计成为一个interface???? 这2个方法完全可以移到AbstractTimerTask上去, 大家爱用不用呗.

这好比建了个厕所, 建造者说肚子不舒服, 占着个坑位就是不拉, 最过分的是, 这个厕所就只有一个坑位......


后记: Quartz是个很不错的替代品, 强大的计划功能, 最重要的是, 它没有强占坑位......
   
最后更新时间:2004-07-29
曾几何时 C++带过来的class概念根深蒂固,那可爱的abstract class是我的“必备常用品”。
然而,自从认识了“Spring”,我就深深的爱上了它,如果能让我早一点认识它,我愿意是在我还是“液体”的时候就跟他结合。
哦,spring给我们带来了诠释interface的“高潮”!我现在就处于这种快感之中!
不过interface---->abstract class--->class
是一般的java 开发定势思维呢!!
   
0 请登录后投票
最后更新时间:2004-07-29
巨寒~~~楼上的。。。
   
0 请登录后投票
最后更新时间:2004-07-29
不错的系列,期待中。。。
   
0 请登录后投票
最后更新时间:2004-07-29
每次ReadOnly的“过门”比较有意思:)
   
0 请登录后投票
最后更新时间:2004-07-29
firebody 写道
曾几何时 C++带过来的class概念根深蒂固,那可爱的abstract class是我的“必备常用品”。
然而,自从认识了“Spring”,我就深深的爱上了它,如果能让我早一点认识它,我愿意是在我还是“液体”的时候就跟他结合。
哦,spring给我们带来了诠释interface的“高潮”!我现在就处于这种快感之中!
不过interface---->abstract class--->class
是一般的java 开发定势思维呢!!


这样算不算叫“Spring”?
   
0 请登录后投票
最后更新时间:2004-07-29
Readonly 写道
后记: Quartz是个很不错的替代品, 强大的计划功能, 最重要的是, 它没有强占坑位......


another one : jcrontab.

However , i like the "Quartz" more .

There are many good jars for u in opensymphony to replace some java.util.* . Of course , you can use the a lot of jakarta-commons libs from apache.

Your article is funny , i like it !
   
0 请登录后投票
最后更新时间:2004-07-30
看了楼主的愚蠢的java.util.TimerTask,发现楼主可能有一些误解,
   首先是为什么TimerTask不设计成为一个interface,我不知道楼主是否有仔细看过Java API Timer系统的实现,在其实现中,数度使用了TimerTask的成员及锁,如果改为接口的话:

    public interface TimerTask {
      public Lock lock();
      public void releaseLock(Lock l);
      public long getPeriod();
      public long getState();
      public long getNextExecutionTime();
      ...
    }

恐怕会有更多的人跳出来说,这个接口怎么那么臃肿,我做的只是很简单的一个定时任务,还要我实现如此之多无关的方法...,或者又说 为什么获取lock方法没有明显标识需要同步,会错误引导开发者云云.

   第二该问题的解决方法其实楼主也给出来了,类似这样的解决方法,我认为也正是Sun的API构架师所要达到的效果

   而说到quartz,我以前只是看过别人使用,没有亲用过,昨天特地下载下来研究了一番.quartz项目的全名叫:Quartz Enterprise Job Scheduler,从名字上可以看出这是为企业级应用而产生的,毫无疑问,同其他企业级的产品一样,它是非常灵活的,而且功能强大,但是它的这些特性也带来了它的构架相对于Java API Timer体系复杂得多的结果,这对于想简单应用的场景来说不免太过杀鸡用牛刀了.
   
0 请登录后投票
最后更新时间:2004-07-30
这个么...在这里讨论技术就好,虽然不是很反对版聊,可这里提供的短消息岂不是等同于虚设? 而且论坛就是论坛,其保护隐私的特性能使人畅所欲言,如果都对应真实身份倒是有消亡的危险.

    其实楼主的行为值得称赞,勇于把自己的看法发表来等待别人指出不足,相比之下以没时间,工作忙的借口等等而逃避技术讨论更让人不好意思.

   最后, 我其实和楼主一样认为Cache实际并不一定要算法...或者说简单存储也是一种算法,上个帖子被封了,没来得及表达...
   
0 请登录后投票
最后更新时间:2004-07-30
其实TimerTask作为client application的一个util的话还是很不错的,简单易用!虽然不是接口,与你自己的程序结合也并不会有什么问题!

我到是觉得它作为server端使用的话最大的问题是Thread不能重用,每次都开一个线程,如果负荷大的的话恐怕系统很快就会崩溃!Doug Lea的concurrent中有些工具在这种情况下就比较合适了。

Quartz的确不错,但是它的Job接口可一点也不可爱,特别是丑陋的JobDetail,JobExecutionContext,我只是要执行我的任务,要知道你的context干吗?在IOC大行其道的今天,实在有些过时。Spring对她的包装就很优雅。值得推荐!
   
0 请登录后投票
论坛首页 Java版

跳转论坛:
JavaEye推荐