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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM