java 多线程 目录:
学习了一段时间的多线程内容,项目中有个定时调度的需求,将之前的需求重新梳理了下,写了一个多线程调用的简单例子,加深学习。这块内容整理完,考虑单独弄一个系统,用线程池来完成,另把memcached也逐步放进来,目前系统已经基本搭建完毕。
定时调度的需求如下:设定任务的开始时间,分为单次调度和循环调度,访问指定的url。
1 packagecom.scheduler;2
3 importjava.io.BufferedReader;4 importjava.io.File;5 importjava.io.FileNotFoundException;6 importjava.io.FileReader;7 importjava.io.IOException;8 importjava.util.ArrayList;9
10
11 /**
12 * 定时调度的小程序13 * @ClassName: schedulerManager14 * TODO15 *@authorXingle16 * @date 2014-8-5 下午5:24:3717 */
18 public classschedulerManager{19 //调度列表,格式如下20 //任务名|开始时间|间隔数量|间隔单位|程序URL地址21 //其中间隔单位用以下表示:年 year,月 month,日 day,时 hour,分 min,秒 sec
22 public staticArrayList tls;23
24 public static voidmain(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(newFileReader(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 = newMonitor();46 monitor.start();47
48 }49 }
其中,监视器如下:
1 packagecom.scheduler;2
3 importjava.text.ParseException;4 importjava.text.SimpleDateFormat;5 importjava.util.Calendar;6 importjava.util.Date;7
8 /**
9 * 监视器10 * 1. 任务列表中,若任务时间到,则新开线程执行任务11 * 2. 对于单次调度,调度后标记移除12 * 3.对于循环调度,当前调度执行完移除,任务列表增加下次循环调度的任务13 * 4. 每次遍历休息1秒14 *15 * @ClassName: Monitor16 *@authorXingle17 * @date 2014-8-5 下午5:25:0118 */
19 public class Monitor extendsThread {20
21 Monitor() {22 }23
24 public voidrun() {25 System.out.println("*** 监视器已启动,开始遍历监视任务列表 ***");26 while (!schedulerManager.tls.isEmpty()) {27 Date date = newDate();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 = newexecTask(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 *@paramtask75 *@return
76 *@authorxingle77 * @data 2014-8-5 下午6:34:2578 */
79 privateString[] 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 = newDate();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 returnnextTime;120 }121 }
监视器的执行任务的子进程:
1 packagecom.scheduler;2
3 importjava.io.IOException;4 importjava.net.HttpURLConnection;5 importjava.net.MalformedURLException;6 importjava.net.URL;7
8 /**
9 * 执行任务10 * 访问指定网址11 * @ClassName: execTask12 *13 *@authorXingle14 * @date 2014-8-5 下午5:39:5915 */
16 public class execTask extendsThread{17
18 String[] task =null;19
20 execTask(String[] task){21 this.task =task;22 }23 public voidrun(){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 * 打开url36 *@paraminurl37 *@return
38 *@authorxingle39 *@throwsIOException40 * @data 2014-8-5 下午7:02:3041 */
42 private boolean openUrl(String inurl) throwsIOException{43
44 URL url = null;45 HttpURLConnection conn = null;46 try{47 url = newURL(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