java 多线程——一个定时调度的例子

java 多线程 目录:

Java 多线程——基础知识

Java 多线程 —— synchronized关键字

java 多线程——一个定时调度的例子

java 多线程——quartz 定时调度的例子

java 多线程—— 线程等待与唤醒

 

学习了一段时间的多线程内容,项目中有个定时调度的需求,将之前的需求重新梳理了下,写了一个多线程调用的简单例子,加深学习。这块内容整理完,考虑单独弄一个系统,用线程池来完成,另把memcached也逐步放进来,目前系统已经基本搭建完毕。

定时调度的需求如下:设定任务的开始时间,分为单次调度和循环调度,访问指定的url。

 

 1 package com.scheduler;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.File;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileReader;
 7 import java.io.IOException;
 8 import java.util.ArrayList;
 9 
10 
11 /**
12  * 定时调度的小程序
13  * @ClassName: schedulerManager
14  * TODO
15  * @author Xingle
16  * @date 2014-8-5 下午5:24:37
17  */
18 public class schedulerManager{
19     //调度列表,格式如下
20     //任务名|开始时间|间隔数量|间隔单位|程序URL地址
21     //其中间隔单位用以下表示:年 year,月 month,日 day,时 hour,分 min,秒 sec
22     public static ArrayList tls; 
23 
24     public static void main(String[] args) {
25         tls = new ArrayList<>();
26         BufferedReader ins = null;
27         File f = new File("D:\\test/tasklist.txt");
28         try {
29             ins = new BufferedReader(new FileReader(f));
30             String line = "";
31             while ((line = ins.readLine()) != null) {
32                 //增加一个是否执行标识,0 未执行
33                 line = line+"|0";
34                 String[] task = line.split("\\|");
35                 tls.add(task);
36             }
37             ins.close();
38         } catch (FileNotFoundException e) {
39             e.printStackTrace();
40         } catch (IOException e) {
41             e.printStackTrace();
42         }
43         
44         // 开启一个监视器
45         Monitor monitor = new Monitor();
46         monitor.start();
47 
48     }
49 }

 

 

其中,监视器如下:

  1 package com.scheduler;
  2 
  3 import java.text.ParseException;
  4 import java.text.SimpleDateFormat;
  5 import java.util.Calendar;
  6 import java.util.Date;
  7 
  8 /**
  9  * 监视器</br> 
 10  * 1. 任务列表中,若任务时间到,则新开线程执行任务</br> 
 11  * 2. 对于单次调度,调度后标记移除</br> 
 12  * 3.对于循环调度,当前调度执行完移除,任务列表增加下次循环调度的任务</br> 
 13  * 4. 每次遍历休息1秒</br>
 14  *
 15  * @ClassName: Monitor
 16  * @author Xingle
 17  * @date 2014-8-5 下午5:25:01
 18  */
 19 public class Monitor extends Thread {
 20 
 21     Monitor() {
 22     }
 23 
 24     public void run() {
 25         System.out.println("*** 监视器已启动,开始遍历监视任务列表 ***");
 26         while (!schedulerManager.tls.isEmpty()) {
 27             Date date = new Date();
 28             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 29             String currTime = sdf.format(date);
 30             for (int i = 0; i < schedulerManager.tls.size(); i++) {
 31                 String[] task = (String[]) schedulerManager.tls.get(i);
 32                 // 任务起始时间
 33                 String sTime = task[1];
 34                 // 比较时间 ,开启一个子进程去执行任务
 35                 if (sTime.equals(currTime) && !task[5].equals("1")) {
 36                     execTask doTask = new execTask(task);
 37                     doTask.start();
 38                     // 已执行标示
 39                     task[5] = "1";
 40                 }
 41 
 42                 // 循环调度的任务
 43                 if ((task[5].equals("1")) && (!task[2].equals("0"))) {
 44                     // 获取循环下次调用的任务
 45                     String[] nexttask = getNextTask(task);
 46                     schedulerManager.tls.add(nexttask);
 47                     System.out.println("**增加循环任务:" + nexttask[0] + " 下次调用时间:"
 48                             + nexttask[1] + " " + nexttask[4] + " 剩余:"
 49                             + schedulerManager.tls.size());
 50                 }
 51             }
 52 
 53             System.out.println("当前时间:" + currTime);
 54             for (int i = 0; i < schedulerManager.tls.size(); i++) {
 55                 String[] task = (String[]) schedulerManager.tls.get(i);
 56                 if (task[5].equals("1")) {
 57                     schedulerManager.tls.remove(i);
 58                     System.out.println("**减少任务:" + task[0] + " " + task[4]
 59                             + " 剩余:" + schedulerManager.tls.size());
 60                 }
 61             }
 62             try {
 63                 sleep(1000);
 64             } catch (Exception se) {
 65 
 66             }
 67         }
 68 
 69     }
 70 
 71     /**
 72      * 循环任务的下次调用任务情况
 73      * 
 74      * @param task
 75      * @return
 76      * @author xingle
 77      * @data 2014-8-5 下午6:34:25
 78      */
 79     private String[] getNextTask(String[] task) {
 80         // 下次调用时间
 81         String[] nextTime = new String[6];
 82         // 开始时间
 83         String start = task[1];
 84         // 间隔数量
 85         int interval = new Integer(task[2]);
 86         // 间隔单位
 87         String unit = task[3];
 88         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 89 
 90         Date sdate = new Date();
 91         try {
 92             sdate = sdf.parse(start);
 93         } catch (ParseException e) {
 94             e.printStackTrace();
 95         }
 96 
 97         Calendar calendar = Calendar.getInstance();
 98         calendar.setTime(sdate);
 99         if (unit.equals("sec")) {
100             calendar.add(Calendar.SECOND, interval);
101         } else if (unit.equals("min")) {
102             calendar.add(Calendar.MINUTE, interval);
103         } else if (unit.equals("hour")) {
104             calendar.add(Calendar.HOUR, interval);
105         } else if (unit.equals("day")) {
106             calendar.add(Calendar.DAY_OF_MONTH, interval);
107         } else if (unit.equals("month")) {
108             calendar.add(Calendar.MONTH, interval);
109         } else if (unit.equals("year")) {
110             calendar.add(Calendar.YEAR, interval);
111         }
112         String next = sdf.format(calendar.getTime());
113         nextTime[0] = task[0];
114         nextTime[1] = next;
115         nextTime[2] = task[2];
116         nextTime[3] = task[3];
117         nextTime[4] = task[4];
118         nextTime[5] = "0";
119         return nextTime;
120     }
121 }

 

监视器的执行任务的子进程:

 1 package com.scheduler;
 2 
 3 import java.io.IOException;
 4 import java.net.HttpURLConnection;
 5 import java.net.MalformedURLException;
 6 import java.net.URL;
 7 
 8 /**
 9  * 执行任务</br>
10  * 访问指定网址
11  * @ClassName: execTask
12  * 
13  * @author Xingle
14  * @date 2014-8-5 下午5:39:59
15  */
16 public class execTask extends Thread{
17 
18     String[] task =null;
19     
20     execTask(String[] task){
21         this.task = task;
22     }
23     public void run(){
24         try {
25             if(!openUrl(task[4])){
26                 //写入错误日志文件
27                 System.out.println("打开错误: "+task.toString());
28             }
29         } catch (IOException e) {
30             e.printStackTrace();
31         }
32     }
33     
34     /**
35      * 打开url
36      * @param inurl
37      * @return
38      * @author xingle
39      * @throws IOException 
40      * @data 2014-8-5 下午7:02:30
41      */
42     private boolean openUrl(String inurl) throws IOException{
43         
44         URL url = null;
45         HttpURLConnection conn = null;
46         try {
47             url = new URL(inurl);
48             conn = (HttpURLConnection) url.openConnection();
49         } catch (MalformedURLException e) {
50             e.printStackTrace();
51         } catch (IOException e) {
52             System.out.println("***************** 连接失败,程序地址 : "+inurl);
53             e.printStackTrace();
54             return false;
55         }
56         if(conn.getResponseCode()!= HttpURLConnection.HTTP_OK){
57             System.out.println("****************** 调度失败!!,程序地址 : "+inurl);
58             return false;
59         }
60         else{
61             System.out.println("********************* 已完成调度,程序地址: "+inurl);
62             return true;
63         }
64         
65     }
66     
67 }

 

这里D:\test\tasklist.txt 中的文本如下:

task1|2014-08-06 11:42:00|5|sec|http://www.baidu.com
task2|2014-08-06 11:42:25|0|min|http://www.sina.com
task3|2014-08-06 19:00:00|3|min|http://www.cnblogs.com/xingele0917/
task4|2014-08-06 19:05:00|2|min|http://pomotodo.com/app/
task5|2014-08-06 18:09:00|1|min|http://www.w3school.com.cn/html5/

 

执行结果(截取一部分):

*** 监视器已启动,开始遍历监视任务列表 ***
当前时间:2014-08-06 11:41:55
当前时间:2014-08-06 11:41:56
当前时间:2014-08-06 11:41:57
当前时间:2014-08-06 11:41:58
当前时间:2014-08-06 11:41:59
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:05 http://www.baidu.com 剩余:6
当前时间:2014-08-06 11:42:00
**减少任务:task1 http://www.baidu.com 剩余:5
********************* 已完成调度,程序地址: http://www.baidu.com
当前时间:2014-08-06 11:42:01
当前时间:2014-08-06 11:42:02
当前时间:2014-08-06 11:42:03
当前时间:2014-08-06 11:42:04
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:10 http://www.baidu.com 剩余:6
当前时间:2014-08-06 11:42:05
**减少任务:task1 http://www.baidu.com 剩余:5
********************* 已完成调度,程序地址: http://www.baidu.com
当前时间:2014-08-06 11:42:07
当前时间:2014-08-06 11:42:08
当前时间:2014-08-06 11:42:09
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:15 http://www.baidu.com 剩余:6
当前时间:2014-08-06 11:42:10
**减少任务:task1 http://www.baidu.com 剩余:5
********************* 已完成调度,程序地址: http://www.baidu.com
当前时间:2014-08-06 11:42:11
当前时间:2014-08-06 11:42:12
当前时间:2014-08-06 11:42:13
当前时间:2014-08-06 11:42:14
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:20 http://www.baidu.com 剩余:6
当前时间:2014-08-06 11:42:15
**减少任务:task1 http://www.baidu.com 剩余:5
********************* 已完成调度,程序地址: http://www.baidu.com
当前时间:2014-08-06 11:42:16
当前时间:2014-08-06 11:42:17
当前时间:2014-08-06 11:42:18
当前时间:2014-08-06 11:42:19
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:25 http://www.baidu.com 剩余:6
当前时间:2014-08-06 11:42:20
**减少任务:task1 http://www.baidu.com 剩余:5
********************* 已完成调度,程序地址: http://www.baidu.com
当前时间:2014-08-06 11:42:21
当前时间:2014-08-06 11:42:22
当前时间:2014-08-06 11:42:23
当前时间:2014-08-06 11:42:24
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:30 http://www.baidu.com 剩余:6
当前时间:2014-08-06 11:42:25
**减少任务:task2 http://www.sina.com 剩余:5
**减少任务:task1 http://www.baidu.com 剩余:4
********************* 已完成调度,程序地址: http://www.baidu.com
********************* 已完成调度,程序地址: http://www.sina.com
当前时间:2014-08-06 11:42:26
当前时间:2014-08-06 11:42:27
当前时间:2014-08-06 11:42:28
当前时间:2014-08-06 11:42:29
**增加循环任务:task1 下次调用时间:2014-08-06 11:42:35 http://www.baidu.com 剩余:5
当前时间:2014-08-06 11:42:30
**减少任务:task1 http://www.baidu.com 剩余:4
********************* 已完成调度,程序地址: http://www.baidu.com

 

转载于:https://www.cnblogs.com/xingele0917/p/3892880.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值