zoukankan      html  css  js  c++  java
  • 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: est asklist.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

  • 相关阅读:
    【转】CentOS8新特性
    【转】Python 库打包分发(setup.py 编写)简易指南
    【转】Python3的venv虚拟环境操作(Linux)
    【转】Qt绘图之QGraphicsScene QGraphicsView QGraphicsItem详解
    【转】Qt 积累
    webapi 参数传递详解
    WPF 字体图标样式
    asp net core mvc 跨域ajax解决方案
    NPOI导出Excel封装
    XML序列化CDATA
  • 原文地址:https://www.cnblogs.com/xingele0917/p/3892880.html
Copyright © 2011-2022 走看看