提到後台任務,最容易想到的恐怕就是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("開關已經關閉,無須設置!");
}
}
}
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();
}
}
index.JSP
<%@ page contentType="text/Html;charset=UTF-8" language="Java" %>
Place your content here
啟動
關閉
on.JSP
<%@ page import="task.MyTask" %>
<%@ page import="task.Test" %>
<%@ page contentType="text/Html;charset=UTF-8" language="Java" %>
<%
MyTask.setOn();
Test.exe();
%>
啟動
關閉
off.JSP
<%@ page import="task.MyTask" %>
<%@ page contentType="text/Html;charset=UTF-8" language="Java" %>
<%
MyTask.setOff();
%>
啟動
關閉
開關狀態被置為開!,任務開始執行!
1
do------------
do------------
do------------
do------------
do------------
開關關閉,正在執行的任務結束後將終止!
do------------
從執行結果上看,基本滿足了以上的需求,下來要做的就是裝飾了,添加線程池的管理,指定多個任務,完善執行器的控制等等。