一个Java Web后台任务执行工具的设计与实现
提到后台任务,最容易想到的恐怕就是Java 中的Timer或者大名鼎鼎的开源定时器Quartz,但是,从本质讲,他们都是定时器,以时间间隔严格的进行间歇性的执行。
如果要做一个可控制性很强的后台任务执行工具,Timer和Quartz都不合适。
先看看要求:任务不随着Web服务器的启动而启动,任务的启动、关闭、重启都通过Web页面来控制,任务是后台的一个线程,一个任务只能用一个线程去执行(单线程队列式的执行方式),在任务关闭的时候,要等着任务执行完成再关闭,保证任务的执行的完整性。
基于以上的要求:没有现成的组建或开源的大饼,只能自己手写了。
分三步:分析、设计、实现。
一、分析
任务是一个线程。------- boolean sw
任务需要开关。------Runnable的静态变量。
任务在反复执行。------ while(sw){ do.....}
任务需要通过一定的方式启动关闭。Test#exe
二、设计
定义一个任务类MyTask,加入开关,并增加设置开关状态的方法,在run方法中循环执行业务。循环条件以开关为准。
定义一个启动任务的工具,比如Test吧,并第一个static方法exe去执行任务,要单线程访问,设置为synchronized的。
做三个简单的页面,index.jsp/on.jsp/off.jsp来控制任务。(页面凑合着搞得,不想浪费太多时间,能说明问题即可)。
三、实现
package task;
/**
* 任务
*
* @author leizhimin 2008-12-25 10:37:22
*/
public class MyTask extends Thread {
private static boolean sw = false;
public void run() {
while (sw) {
//进行的所有业务
for (int i = 0; i < 9999999; i++) ;
System.out.println("do------------");
}
}
public static void setOn() {
if (sw == false) {
System.out.println("开关状态被置为开!,任务开始执行!");
sw = true;
} else {
System.out.println("开关已经打开,无须设置!");
}
}
public static void setOff() {
if (sw == true) {
System.out.println("开关关闭,正在执行的任务结束后将终止!");
sw = false;
} else {
System.out.println("开关已经关闭,无须设置!");
}
}
}
/**
* 任务
*
* @author leizhimin 2008-12-25 10:37:22
*/
public class MyTask extends Thread {
private static boolean sw = false;
public void run() {
while (sw) {
//进行的所有业务
for (int i = 0; i < 9999999; i++) ;
System.out.println("do------------");
}
}
public static void setOn() {
if (sw == false) {
System.out.println("开关状态被置为开!,任务开始执行!");
sw = true;
} else {
System.out.println("开关已经打开,无须设置!");
}
}
public static void setOff() {
if (sw == true) {
System.out.println("开关关闭,正在执行的任务结束后将终止!");
sw = false;
} else {
System.out.println("开关已经关闭,无须设置!");
}
}
}
package task;
/**
* 任务的执行工具
*
* @author leizhimin 2008-12-25 10:39:18
*/
public class Test {
static int i = 0;
public synchronized static void exe() throws InterruptedException {
System.out.println(++i);
MyTask myTask = new MyTask();
myTask.start();
Thread.sleep(100);
}
public static void main(String[] args) throws InterruptedException {
exe();
}
}
/**
* 任务的执行工具
*
* @author leizhimin 2008-12-25 10:39:18
*/
public class Test {
static int i = 0;
public synchronized static void exe() throws InterruptedException {
System.out.println(++i);
MyTask myTask = new MyTask();
myTask.start();
Thread.sleep(100);
}
public static void main(String[] args) throws InterruptedException {
exe();
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Simple jsp page</title></head>
<body>Place your content here
<a href="on.jsp">启动</a>
<a href="off.jsp">关闭</a>
</body>
</html>
<html>
<head><title>Simple jsp page</title></head>
<body>Place your content here
<a href="on.jsp">启动</a>
<a href="off.jsp">关闭</a>
</body>
</html>
on.jsp
<%@ page import="task.MyTask" %>
<%@ page import="task.Test" %>
<%@ page import="task.Test" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Simple jsp page</title></head>
<body>
<%
MyTask.setOn();
Test.exe();
%>
<a href="on.jsp">启动</a>
<a href="off.jsp">关闭</a>
</body>
</html>
<html>
<head><title>Simple jsp page</title></head>
<body>
<%
MyTask.setOn();
Test.exe();
%>
<a href="on.jsp">启动</a>
<a href="off.jsp">关闭</a>
</body>
</html>
off.jsp
<%@ page import="task.MyTask" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Simple jsp page</title></head>
<body>
<%
MyTask.setOff();
%>
<a href="on.jsp">启动</a>
<a href="off.jsp">关闭</a>
</body>
</html>
<html>
<head><title>Simple jsp page</title></head>
<body>
<%
MyTask.setOff();
%>
<a href="on.jsp">启动</a>
<a href="off.jsp">关闭</a>
</body>
</html>
开关状态被置为开!,任务开始执行!
1
do------------
do------------
do------------
do------------
do------------
开关关闭,正在执行的任务结束后将终止!
do------------
1
do------------
do------------
do------------
do------------
do------------
开关关闭,正在执行的任务结束后将终止!
do------------
从执行结果上看,基本满足了以上的需求,下来要做的就是装饰了,添加线程池的管理,指定多个任务,完善执行器的控制等等。
本文转自 leizhimin 51CTO博客,原文链接:http://blog.51cto.com/lavasoft/122405,如需转载请自行联系原作者