java 多线程 目录:

Java 多线程——基础知识

Java 多线程 —— synchronized关键字

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

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

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

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

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

 package com.scheduler;

 import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList; /**
* 定时调度的小程序
* @ClassName: schedulerManager
* TODO
* @author Xingle
* @date 2014-8-5 下午5:24:37
*/
public class schedulerManager{
//调度列表,格式如下
//任务名|开始时间|间隔数量|间隔单位|程序URL地址
//其中间隔单位用以下表示:年 year,月 month,日 day,时 hour,分 min,秒 sec
public static ArrayList tls; public static void main(String[] args) {
tls = new ArrayList<>();
BufferedReader ins = null;
File f = new File("D:\\test/tasklist.txt");
try {
ins = new BufferedReader(new FileReader(f));
String line = "";
while ((line = ins.readLine()) != null) {
//增加一个是否执行标识,0 未执行
line = line+"|0";
String[] task = line.split("\\|");
tls.add(task);
}
ins.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} // 开启一个监视器
Monitor monitor = new Monitor();
monitor.start(); }
}

其中,监视器如下:

 package com.scheduler;

 import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date; /**
* 监视器</br>
* 1. 任务列表中,若任务时间到,则新开线程执行任务</br>
* 2. 对于单次调度,调度后标记移除</br>
* 3.对于循环调度,当前调度执行完移除,任务列表增加下次循环调度的任务</br>
* 4. 每次遍历休息1秒</br>
*
* @ClassName: Monitor
* @author Xingle
* @date 2014-8-5 下午5:25:01
*/
public class Monitor extends Thread { Monitor() {
} public void run() {
System.out.println("*** 监视器已启动,开始遍历监视任务列表 ***");
while (!schedulerManager.tls.isEmpty()) {
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String currTime = sdf.format(date);
for (int i = 0; i < schedulerManager.tls.size(); i++) {
String[] task = (String[]) schedulerManager.tls.get(i);
// 任务起始时间
String sTime = task[1];
// 比较时间 ,开启一个子进程去执行任务
if (sTime.equals(currTime) && !task[5].equals("1")) {
execTask doTask = new execTask(task);
doTask.start();
// 已执行标示
task[5] = "1";
} // 循环调度的任务
if ((task[5].equals("1")) && (!task[2].equals("0"))) {
// 获取循环下次调用的任务
String[] nexttask = getNextTask(task);
schedulerManager.tls.add(nexttask);
System.out.println("**增加循环任务:" + nexttask[0] + " 下次调用时间:"
+ nexttask[1] + " " + nexttask[4] + " 剩余:"
+ schedulerManager.tls.size());
}
} System.out.println("当前时间:" + currTime);
for (int i = 0; i < schedulerManager.tls.size(); i++) {
String[] task = (String[]) schedulerManager.tls.get(i);
if (task[5].equals("1")) {
schedulerManager.tls.remove(i);
System.out.println("**减少任务:" + task[0] + " " + task[4]
+ " 剩余:" + schedulerManager.tls.size());
}
}
try {
sleep(1000);
} catch (Exception se) { }
} } /**
* 循环任务的下次调用任务情况
*
* @param task
* @return
* @author xingle
* @data 2014-8-5 下午6:34:25
*/
private String[] getNextTask(String[] task) {
// 下次调用时间
String[] nextTime = new String[6];
// 开始时间
String start = task[1];
// 间隔数量
int interval = new Integer(task[2]);
// 间隔单位
String unit = task[3];
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date sdate = new Date();
try {
sdate = sdf.parse(start);
} catch (ParseException e) {
e.printStackTrace();
} Calendar calendar = Calendar.getInstance();
calendar.setTime(sdate);
if (unit.equals("sec")) {
calendar.add(Calendar.SECOND, interval);
} else if (unit.equals("min")) {
calendar.add(Calendar.MINUTE, interval);
} else if (unit.equals("hour")) {
calendar.add(Calendar.HOUR, interval);
} else if (unit.equals("day")) {
calendar.add(Calendar.DAY_OF_MONTH, interval);
} else if (unit.equals("month")) {
calendar.add(Calendar.MONTH, interval);
} else if (unit.equals("year")) {
calendar.add(Calendar.YEAR, interval);
}
String next = sdf.format(calendar.getTime());
nextTime[0] = task[0];
nextTime[1] = next;
nextTime[2] = task[2];
nextTime[3] = task[3];
nextTime[4] = task[4];
nextTime[5] = "0";
return nextTime;
}
}

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

 package com.scheduler;

 import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL; /**
* 执行任务</br>
* 访问指定网址
* @ClassName: execTask
*
* @author Xingle
* @date 2014-8-5 下午5:39:59
*/
public class execTask extends Thread{ String[] task =null; execTask(String[] task){
this.task = task;
}
public void run(){
try {
if(!openUrl(task[4])){
//写入错误日志文件
System.out.println("打开错误: "+task.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 打开url
* @param inurl
* @return
* @author xingle
* @throws IOException
* @data 2014-8-5 下午7:02:30
*/
private boolean openUrl(String inurl) throws IOException{ URL url = null;
HttpURLConnection conn = null;
try {
url = new URL(inurl);
conn = (HttpURLConnection) url.openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
System.out.println("***************** 连接失败,程序地址 : "+inurl);
e.printStackTrace();
return false;
}
if(conn.getResponseCode()!= HttpURLConnection.HTTP_OK){
System.out.println("****************** 调度失败!!,程序地址 : "+inurl);
return false;
}
else{
System.out.println("********************* 已完成调度,程序地址: "+inurl);
return true;
} } }

这里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

java 多线程——一个定时调度的例子的更多相关文章

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

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  2. java 多线程 一个博客

    http://blog.csdn.net/a352193394/article/category/2563875 Java多线程之~~~线程安全容器的非阻塞容器 在并发编程中,会经常遇到使用容器.但是 ...

  3. Java多线程-线程的调度(休眠)

    Java线程调度是Java多线程的核心,只有良好的调度,才能充分发挥系统的性能,提高程序的执行效率. 这里要明确的一点,不管程序员怎么编写调度,只能最大限度的影响线程执行的次序,而不能做到精准控制. ...

  4. Spring4+Springmvc+quartz实现多线程动态定时调度

    scheduler定时调度系统是大多行业项目都需要的,传统的spring-job模式,个人感觉已经out了,因为存在很多的问题,特别是定时调度的追加.修改.删除等,需要修改xml,xml的配置生效无非 ...

  5. JAVA中的定时调度(Timer和TimerTask)

    某些时候我们需要定时去完成一些任务,这里举一个例子:我们需要在3秒钟后打印当前系统时间,此后每隔5秒重复此操作.代码如下: import java.util.TimerTask; import jav ...

  6. Java中的定时调度

    Timer类是一个线程设施,用于实现在某个时间或者某一段时间后安排某个任务执行一次或者定期重复执行.需要与TimerTask配合使用. TimerTask类用来实现由Timer安排的一次或重复执行的某 ...

  7. Java多线程-线程的调度(合并)

    线程的合并的含义就是将几个并行线程的线程合并为一个单线程执行,应用场景是当一个线程必须等待另一个线程执行完毕才能执行时可以使用join方法. join为非静态方法,定义如下:void join(): ...

  8. Java多线程-线程的调度(守护线程)

    本文转自http://www.cnblogs.com/linjiqin/p/3210004.html 感谢作者 守护线程与普通线程写法上基本没啥区别,调用线程对象的方法setDaemon(true), ...

  9. Java多线程-线程的调度(优先级)

    与线程休眠类似,线程的优先级仍然无法保障线程的执行次序.只不过,优先级高的线程获取CPU资源的概率较大,优先级低的并非没机会执行. 线程的优先级用1-10之间的整数表示,数值越大优先级越高,默认的优先 ...

随机推荐

  1. [POJ1830]开关问题(高斯消元,异或方程组)

    题目链接:http://poj.org/problem?id=1830 题意:中文题面,求的是方案数. 首先可以知道, 如果方案数不止一个的话,说明矩阵行列式值为0,即存在自由变元,由于变量只有两种状 ...

  2. [CF738A]Interview with Oleg(模拟)

    题目链接:http://codeforces.com/contest/738/problem/A 题意:把ogo..ogo替换成***. 写的有点飘,还怕FST.不过还好 #include <b ...

  3. C语言中strdup函数使用方法

    头文件:#include <string.h> 定义函数:char * strdup(const char *s); 函数说明:strdup()会先用malloc()配置与参数s 字符串相 ...

  4. FJNU 1155 Fat Brother’s prediction(胖哥的预言)

    FJNU 1155 Fat Brother’s prediction(胖哥的预言) Time Limit: 1000MS   Memory Limit: 257792K [Description] [ ...

  5. Scrum Meeting---Four(2015-10-28)

    今日已完成任务和明日要做的任务 姓名 今日已完成任务 今日时间 明日计划完成任务 估计用时 董元财 今日我完成了数据库表的设计以及创建 3h 进行Java Web工程的编写 4h 胡亚坤 用户之间的通 ...

  6. 从POI到O2O 看百度地图如何走出未来之路

    近期O2O的烧钱融资大战如火如荼,有人已经把O2O大战,用乌合之众的群体心理失控来形容.其实厂商都不傻,O2O烧钱大家都知道,但是大家还知道O2O背后这块大蛋糕价值"万亿级". 有 ...

  7. asp.net开发中经常用到的方法

    ---天气插件--- <iframe width="560" scrolling="no" height="23" framebord ...

  8. Python学习笔记7—集合

    set 拥有类似 dict 的特点:可以用{}花括号来定义:其中的元素没有序列,也就是是非序列类型的数据;而且,set 中的元素不可重复,这就类似 dict 的键. >>> s1 = ...

  9. git本地文件回滚操作

    今天有几个文件改在了其他分支上.需要回滚. 参考了下面两篇文章: Link    Link 简单讲,分多个不同的阶段: 1. 用git status命令看,发现是unstaged,那么就是只在work ...

  10. iOS开发之用Xcode 在真机上截屏与模拟器截屏

    一.真机截屏 1.打开Xcode 6 2.在xcode 选择模拟器或者真机设备的地方选中你的真机 3.Debug-->View Debugging-->Take Screenshot of ...