皮皮左耳

evoleht

 

2010年8月11日

Scheduler定时器

首先添加所需要的类包:quartz-1.5.2.jar,quartz-all-1.5.2.jar,quartz-jboss-1.5.2.jar 
//设置定时作业
 public void startScheduler(HttpServletRequest requests)throws SchedulerException{
  try{
   
//建立作业调度器
   Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
   //判断作业调度内是否有作业,如果有将其删除
   
if (!scheduler.isShutdown()) {
                scheduler.deleteJob("ReceiveOnTimed", Scheduler.DEFAULT_GROUP);
            }
   //删除调度器的作业后,新建一个我们现在要完成的作业,该作业所需要的类是ReceiveJobd.class,作业名字是ReceiveOnTimes,所属分组是Scheduler.DEFAULT_GROUP
           
JobDetail jobDetail = new JobDetail("ReceiveOnTimed",
                                                Scheduler.DEFAULT_GROUP,
                                                ReceiveJobd.class);

            int m = ips.length;
            int n = tablenames.length;
            //向作业内设置要传入的参数
           
jobDetail.getJobDataMap().put("scheduler", scheduler);
            jobDetail.getJobDataMap().put("ipLength", m);
            jobDetail.getJobDataMap().put("tablenameLength", n);
            jobDetail.getJobDataMap().put("wcx",wc);
            for (int i = 0; i < m; i++) {
                jobDetail.getJobDataMap().put("ip" + i, ips[i]);
                for (int j = 0; j < n; j++) {
                    jobDetail.getJobDataMap().put("tablename" + j, tablenames[j]);
                }
            }
           
//建立触发器,判断何时触发该作业,参数为触发器的名称,触发器分组,作业名称,作业分组,时间设定
           
Trigger trigger = new CronTrigger("ReceiverOnTimeTriggerd",
                                              scheduler.DEFAULT_GROUP,
                                              "ReceiveOnTimed",
                                              scheduler.DEFAULT_GROUP, time);
           
//将作业和触发器添加到调度器
           
scheduler.scheduleJob(jobDetail, trigger);
           
//按照设置开始调度
            scheduler.start();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
 
具体作业类的处理:
 package com.bodhiya.schsystem.business;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Scheduler;
import org.springframework.web.context.WebApplicationContext;

public class ReceiveJobd implements Job{
 public void ReceiveJobd(){
 }
 
//作业具体实现的功能
 public void
execute(JobExecutionContext context) throws
    JobExecutionException
{
     try {
           
            //建立JobDataMap对象,用来接收传递的参数
           
JobDataMap dataMap = context.getMergedJobDataMap();
            int ipLength = dataMap.getInt("ipLength");
            int tablenameLength = dataMap.getInt("tablenameLength");
           
WebApplicationContext wc=(WebApplicationContext)dataMap.get("wcx");
           
            String ip = "";
            String tablename = "";
            for (int i = 0; i < ipLength; i++) {
                ip = dataMap.getString("ip" + i);
                for (int j = 0; j < tablenameLength; j++) {
                    tablename = dataMap.getString("tablename" + j);
                    ExchangeAccess ea=new ExchangeAccess(ip,tablename,wc);
                     
//启动线程
                    ea.start();
                }
            }
           
Scheduler scheduler = (Scheduler) dataMap.get("scheduler");
            scheduler.deleteJob("ReceiveOnTimed", Scheduler.DEFAULT_GROUP);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
 }
}

posted @ 2010-08-11 18:40 皮卡诺 阅读(304) | 评论 (0)编辑 收藏

quartz-scheduler 定时器

        在阐述quartz是个什么东西之前,我先说个事。很多时候,我们经常在台历上标注出,某一天是某人的生日,某一天有某个重要的事情,给自己一个提醒。一个台历加上所要做的事情的内容,就是一个scheduler。计算机系统,是帮助人们完成既定事务的。所以,我们希望,把“日程规划+具体事务”,交给系统,系统就能按照我们的要求自动去工作。
    好了,quartz就是这么一个东西。我们只需要定义好时间表,并对应指定的操作,它就能够按照我们的要求在指定时间驱动指定的工作,如此简单。

       quartz中,所有需要驱动的工作,都是实现job接口的类。job接口很简单,就只有一个excute()方法,只要把这个类交给quartz,它就会自动去执行这个方法。方法里面定义的就是我们真正需要进行的工作,恩,这都没有什么问题。

        现在的问题在于,很多时候我们需要执行的工作类,是外部类,并没有继承job接口。也就是说,我们希望quartz能够驱动任意的类的任意方法,这该怎么办?这也是我第一阶段的一个小目标。

    一开始我想改变quartz的驱动方式,也就是改变runshell里面的东西,后来发现,这太复杂了,这是quartz最核心的东西,动一发而牵全身。我只是想利用quartz的优势,并不想大规模的改动。
    走了不少弯路之后,想了一个不错的方案。就是,我们只需要定义好所需要的类名、方法名、方法需要的参数,然后利用reflect,来实例化类,然后invoke指定方法。而把这些工作放在一个通用的job模板中的excute方法,这样,我们只需要把指定参数传入这个通用job模板,然后直接驱动此job就能实现我们上面的目标。
    参数传递采用的方案是:
    1、数据源。把我们需要指定的信息以配置文件的方式给出,主要是,工作组、工作名、工作对应的类,指定的方法,所需的参数。
    2、数据传递。写一个metadata用来包装这些信息,这样做是为了将来管理的方便。然后用metadata来初始化jobdetail,重写工作组、工作名,将类信息保存在jobDataMap中,然后在执行excute的时候,再把这些信息取出来。
    3、工作执行。利用reflect技术,执行指定类的指定方式。
    4、数据返回。excute结束之前,把需要返回的数据放在jobDataMap中,scheduler结束之前,把这些数据从jobDataMap中取出来。
    完美的方案,开心一下!

    下一步研究quartz的另外一个大部分 时间表。

    quartz的一些基本概念

        Job 与 JobDetail

        Job是quartz中最基本的概念了,Job做为一个接口只有一个execute()方法等待实现,理论上所有用quartz执行的job都需要实现这个接口,但是现在大多数的系统都不会服从这种约束,而希望能够更自由的调用原有系统中的类的方法。实现自由调用,有两个途径,我上一节总结中的那个方案是一个简单的途径,另外一个途径就是借助于spring的class bean,这个将在后面介绍。
        StatefullJob接口: 无状态任务对应的JobDataMap可以认为是只读的,而有状态的任务在多次执行过程中保留对JobDataMap所作的修改,一个后果是有状态任务无法被并发执行。上面这句话是抄袭的,事实上我还是不是很清楚二者究竟的区别?
    
        JobDetail是用来包装Job实例的具体细节的。Job以class的方式传入JobDetail,quartz会自动实例化Job类的。同时需要规定job的name和group,在jobdetail的validate()下,一个job是必须有name和group属性,并且二者组合标示唯一的job。JobDetail中的一些重要数据存放在JobDataMap中,这个map可以用来在控制程序和job内传递需要传递的参数。
        JobDetail还有三个重要的boolean值的属性,分别是durability、volatility、shouldRecover。这三个属性默认是false,主要在数据库操作的时候起作用。

        Trigger时间调度

        相对于job,trigger简单一些。所谓的时间调度,就是设置job执行的时间表。Trigger主要分为SimpleTrigger和CronTrigger两大类。前者主要是以1/1000
为单位的简单时间,可是设置startTime、endTime、repeatCount、repeatInterval等主要参数。CronTrigger的详细用法参看quartz文档的的CronTriggers Tutorial。
        scheduler.schedulerJob(jobDetail, trigger);将JobDetail和对应的Trigger部署到scheduler中,然后根据trigger的定义,自动执行指定job。
        Calendar这个类用来标识出特殊的时间,scheduler根据trigger执行job的时候,如果遇到这些标识出的特殊时间则不执行job。Calendar具体的接口有BaseCalendar、AnnualCalendar、HolidayCalendar、MonthlyCalendar、WeeklyCalendar等等。calendar的具体用法参看quartz的文档。
        Misfire Instruction....设定当trigger错过了触发时刻的时候需要采取的处理策略
        TriggerUtils相当于一个trigger factory,方便我们取得特殊trigger的实例,而不用自己去构造。

        Listener是用来监听quartz的执行过程的,主要有JobListener,TriggerListener,SchedulerListener。joblistener监听一个job在quartz中执行的待执行,禁止执行,执行完毕三个状态。TriggerListener监听trigger触发、完成、错过、禁止四个状态。SchedulerListener监听scheduler执行过程的一些状态,具体参看SchedulerListener的源代码。

转自:http://flyinglife.javaeye.com/blog/74553
另:http://forums.opensymphony.com/category.jspa?categoryID=8。
另外推荐一个java的blog:http://www.blogjava.net/javaora/。

posted @ 2010-08-11 18:28 皮卡诺 阅读(1003) | 评论 (0)编辑 收藏

【java】位、字节、汉字、字符的关系

bit、byte、位、字节、汉字的关系


        1 bit     = 1  二进制数据
        1 byte  = 8  bit
        1 字母 = 1  byte = 8 bit
        1 汉字 = 2  byte = 16 bit


1. bit:位
    一个二进制数据0或1,是1bit;

2. byte:字节
    存储空间的基本计量单位,如:MySQL中定义 VARCHAR(45)  即是指 45个字节;
    1 byte = 8 bit

3. 一个英文字符占一个字节;
    1 字母 = 1 byte = 8 bit

4. 一个汉字占2个字节;
    1 汉字 = 2 byte = 16 bit

5. 标点符号
    A>.  汉字输入状态下,默认为全角输入方式;
    B>.  英文输入状态下,默认为半角输入方式;

    C>.  全角输入方式下,标点符号占2字节;
    D>.  半角输入方式下,标点符号占1字节;

    故:汉字输入状态下的字符,占2个字节 (但不排除,自己更改了默认设置);
            英文输入状态下的字符,占1个字节 (但不排除,自己更改了默认设置);

 

        老美在发明电脑时,肯定以自己的英文字母--即他们自认为的字符为最小的存储计量单位,于是也就有了不规范的1字符=1byte, 岂不知还有我们伟大的汉字计量单位,NND,一个汉字也是一个字符,我们的1汉字字符就等于2byte,后来,他们可能意识到这个尴尬的问题,于是又标榜为:一个字母为一个标准字符,去球吧,谁整天没事说个字符还“标准字符”,所以啊,个人认为:字符,不能用于标准的计量单位。
--------------------------------
补充:
    计算机对各国语言的支持度,可分为以下三个阶段,如图:


更详细参考:http://www.regexlab.com/zh/encoding.htm 


转自http://www.blogjava.net/myfly/archive/2008/09/24/230875.html

posted @ 2010-08-11 10:50 皮卡诺 阅读(852) | 评论 (0)编辑 收藏

仅列出标题  

导航

统计

常用链接

留言簿

随笔分类

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜