Design of a Java background program

xiaoxiao2021-03-06  92

Author: Chen Gang, Guilin, 97, graduated from the Department of Mathematics, Guangxi Normal University, temporarily at IBM China Research Center, a part-time engaged in software development, focus on java platform software development (2004.2-?). Email: Glchengang@hotmail.com Blog: Glchengang.yeah.net Many systems require a program that runs uninterrupted in the background to periodically perform certain system tasks. This is similar to the functionality of the program tasks from Windows. I participated in the development of a network management project of a provincial Unicom for a year and a half before, and I have written such a background program. It should be uninterrupted from various types of data files (each file has Agreement) and interpret these files into a record into the database. This background program uses the thread in Java. Due to the complexity of the thread, it is difficult to debug, very unfortunate this background program is very unstable, and there will be one or two times a week will stop in the process, the reason is not found today. Behind my heart.

Taining today, I have been fortunate to participate in IBM a development project. This project also needs a similar background running program. The task of this program is to check the data in the database every other day, and perform actions in accordance with certain conditional records. The task is very simple. For the future expansion, I designed this into a multi-task-managed background program. Week did not set up two tasks in the same time, once every 10 seconds, another task executed every 1 second, running two days, running is good. It is estimated that many friends will face the same problem with me, here will publish the procedures and code, and hope to have interest to study.

First, the program run interface:

1, the total console

2, the setting interface of the planned task.

3, the console output result.

Second, the program development environment:

Developed with Java (JDK 1.4), the graphical interface develops using the Eclipse (version 2.1.3) SWT mode. Run host: P4 2.6 1G memory WindowsXP operating system

Third, prepare.

Develop such programs, it is best not to use Java threads to program, which will increase unnecessary complexity and difficulty, and effort is not good. There is a package java.util.timer in Java package to encapsulate a thread, we can call it to schedule. Let's first look at a simple example:

Import java.util.timer;

Import java.util.timertask;

public

Class Reminder {

Timer Timer;

Public Reminder

INT Seconds) {

Timer =

New Timer ();

Timer.schedule

New transindtask (), seconds * 1000); // parameter requirements are converted into milliseconds

}

public

Static

void main (string args []) {

New Reminder (5); // 5 seconds after running

}

/ ** An internal class that encapsulates the task to run * /

Class Remindtask

Extends Timertask {

public

Void Run () {

System.out.println ("Task Run ...");

Timer.cancel (); // End all the tasks in Timer

}

}

}

Here, there are two Java class Timer and Timertask. After we inherit the Timertask class, we will encapsulate its RUN method; Timer can manage thousands of tasks (Timertask), note that the same task object cannot be added twice to the Timer. For pairs (although the task of execution is the same, two task objects):

Timer.schedule

New remindtask (), seconds * 1000);

Timer.schedule

New remindtask (), seconds * 1000);

wrong

Remindtask Task =

New remindtask ();

Timer.schedule (Task, Seconds * 1000);

Timer.schedule (Task, Seconds * 2000);

Fourth, design.

Main class diagram

Description:

Design of the mission class. Let's create an abstract class AbstractTimertask, this class directly into the Timertask class, providing Timertask package. Then all specific tasks (such as: Timertask_1) inherit from AbstractTimertask.

Import java.util.timertask;

public

Abstract

Class AbstractTimertask

Extends Timertask {

Taskentry taskentry; // Task Record

Public AbstractTimertask (Taskentry Taskentry) {

THIS.TASKENTRY = Taskentry;

}

/ *

* Generate a new instance is equivalent to cloning itself; the reason is:

The same task object cannot be added twice to Timer

* The Taskentry class will see its method

* /

Abstract AbstractTimertask getCloneObject ();

}

Below is a source code for its implementation. We can write the code to run the task in this class.

Import java.util.calendar;

public

Class Timertask_1

Extends abstracttimertask {

PUBLIC TIMERTASK_1 (Taskentry Taskentry) {// Construction Method

Super (taskentry);

}

Public AbstractTimertask getCloneObject () {

Return

NEW TIMERTASK_1 (Taskentry);

}

public

Void Run () {

/ * Write the program you want to perform here. . . . . * /

System.out.println ("??:" taskentry.getname () "Run once");

this.taskentry.taskstart (); // Run the next time point task

}

}

In the AbstractTimertask class, there is a taskenTry field, which is a core class of this design. It represents a complete task record, each task class, and its running plan are packaged in this class, the source code is as follows. Timer and AbstractTimertask have said before, then what is TimePlan to do?

Import java.util.calendar;

Import java.util.date;

Import java.util.timer;

Import mytimer.util.util;

/ ** Task record class * /

public

Class taskentry {

public

Static

Final

INT task_start = 0; // Defines two representation task recording state constants public

Static

Final

INT task_stop = 1;

Private long Oid; // Task ID number, unique

Private string name; // Task Name

Private

Int state = task_stop; // task status (start / stop)

Private Timer Timer; // Java Timer

PRIVATE TIMEPLAN TIMEPLAN; // Time Plan Type

Private AbstractTimertask Timertask; // The seed object of the task class, is constantly cloned by this object

Private AbstractTimertask runtimertask; // Current task of running plan

/ **

* Itaskentry.taskstart () -> Timertask.run () -> itaskentry.taskstart ()

* Form a loop loop. This method is responsible for starting the tasks of this class

* /

public

Void taskstart () {

IF (TimePlan.Havenext ()) {

Date Date = Timeplan.nextdate (); // Get task planning time

Runtimertask = Timertask.getCloneObject (); // Get a task (copy)

Timer.schedule (runtimertask, date); // joining the plan queue

// Print information about the planned task to run

Calendar c = calendar.getInstance ();

C.SetTimeInmillis (RuntimeTask.scheduledExecutionTime ());

System.out.println (Util.Datetolongstr (c.gettime ()) "will run" name);

}

Else {

State = Task_Stop;

System.out.println (Name "End");

}

}

/ ** Stop Task * /

public

Void taskstop () {

IF (runtimertask! =

NULL) {

// Print information

Calendar c = calendar.getInstance ();

C.SetTimeInmillis (RuntimeTask.scheduledExecutionTime ());

System.out.println ("Plan:" Util.datetolongstr (C.getTime ()) "Run" Name "Termination");

// Terminate this task, call timer.cancel () is to terminate all tasks in Timer.

Runtimertask.cancel ();

}

Else {

System.out.println (Name "Not Entering Executive Plan");

}

}

......... Get / set method for some properties (omitted)

/ ** Listening class (internal class) * /

public

Static

Class DatebeforeTodayException

Extends nullpointerserException {

PRIVATE DATE;

Public DatebeforeToDayException (Date Date) {

THIS.DATE = DATE;

Public string toString () {

Return "plan time (" Util.Datetolongstr (Date)) is earlier than the current time ";

}

}

1. Timeplan is an interface (INTERFACE), which means "Run Plan", which provides three run planning schemes (see the front image: Planning task setting interface):

One-time operation.

Run every other period of time.

Choose that day of running in a week.

It is designed to be an interface to expand in the future. If you want to add new time schemes, you only need to inherit this interface to write a new implementation. The class diagrams of three time schemes are as follows:

Description:

a) TimePlan encapsulates five methods, other Havenext () and Nextdate () most important, this two methods imitate the design form of the collection of collections in Java, the code is as follows:

Import java.util.date;

// Time Planning Program

public

Interface Timeplan {

Boolean Havenext (); // Judging that there is no next planning time

Date nextddate (); // Get the next planning time

Date getcurrentdate (); // get start time

Void setCurrentDate (Date Date); // Design start time

String getTimeplanString (); // Show text description of the running plan solution

}

b) AbstractTimePlan is this abstract class, main purpose is to write a public method of some subclasses here. code show as below:

Import java.util.date;

public

Abstract

Class AbstractTimePlan

Implements TimePlan {

// Record the first point of time of the plan, except for the new start time, otherwise no longer change

Protected Date Currentdate;

/ *

When the time point of the current plan, it is updated every time you plan.

It seems that this should be called CurentDate, Sorry doesn't want to change again.

* /

Protected Date Plandate;

public

Boolean HAVENEXT () {

Return (Plandate! =

NULL);

}

Public Date getcurrentdate () {

Return Currentdate;

}

public

Void setcurrentdate (date date) {

Currentdate = DATE;

PLANDATE = DATE; // When assigns a currentdate value, it also assigns a Plandate.

}

}

c) Then we look at the source code of the three planning schemes:

// "One-time operation" plan plan

Import java.util.date;

public

Class TimePlanonce

Extends AbstractTimePlan {

Public Date nextDate () {

/ / Save the current planning time in the intermediate variable

Date returndate =

this.plandate;

// Call the next planning time. No next one is set to NULL

this.plandate =

NULL;

/ / Judgment the planning time without condition

IF (returndate ==

NULL)

Throw

New NullPointersRexception ("No Next Plan Date");

Return Returndate;

}

Public string gettimeplanstring () {return "runs at once, running time: (Print this.currentdate)";

}

}

// "Periodic Interval" Time Plan Program

Import java.util.date;

public

Class TimePlanperiod

Extends AbstractTimePlan {

public

Static

Final

INT Hour = 0;

public

Static

Final

INT day = 1;

Private

INT SPATITIME; // Interval, unit millisecond

Private

int TimeType;

Public Date nextDate () {

/ / Save the current planning time in the intermediate variable

Date returndate =

this.plandate;

// Call the next planning time. No next one is set to NULL

INT MilliseCond = 0;

IF (TimeType == Hour) MilliseCond = SpaceTime * 1000; // hour * 60 * 60 * 1000;

IF (TimeType == Day) MilliseCond = SpaceTime * 24 * 60 * 60 * 1000; //

Plandate = Util.dateAddspaceMilliseCond (Plandate, MilliseCond);

/ / Judgment the planning time without condition

IF (returndate ==

NULL)

Throw

New NullPointersRexception ("No Next Plan Date");

Return Returndate;

}

Public string gettimeplanstring () {

IF (TimeType == Hour)

RETURN "The first time runs on: Currentdate. and run once every spacetime hour";

IF (TimeType == Day)

Return "is running on: Currentdate. Every time Spacetime is running once."

""; "

}

public

INT getSpacetime () {

Return SpaceTime;}

public

INT getTimetyPE () {

Return TimeType;}

public

Void setspaceetime

INT i) {spacetime = i;}

public

Void setTimetyPE

INT i) {TIMETYPE = i;}

}

/ ** Select a few days for a week, let this day to run the task at the same time, you must choose one day in the week * /

Import java.util.calendar;

Import java.util.date;

public

Class TimeplanselectWeek

Extends AbstractTimePlan {

Private

Static Calendar C = Calendar.GetInstance (); // Get a calendar instance

Private

Static

INT SpaceMilliseCond = 0; // Interval, unit milliseconds

Private

Boolean [] SelectWeek =

New

Boolean [7]; // 0 is Sunday, 1 is Monday

Public Date nextDate () {

Date returndate =

NULL;

if (! isselectweek (plandate)) // If this day is not a day, the day, a day, a day, PLANDATE = GetNextDate (Plandate);

Returndate = plandate;

PLANDATE = GetNextdate (Plandate);

/ / Judgment the planning time without condition

IF (returndate ==

NULL)

Throw

New NullPointersRexception ("No Next Plan Date");

Return Returndate;

}

// Call the next planning time. No next one is set to NULL

Private date getnextdate (date date) {

Date Tempdate = DATE;

Date returndate =

NULL;

FOR

INT i = 0; i <7; i ) {

Tempdate = Util.dateAddspacemilliseCond (Tempdate, SpacemilliseCond);

IF (ISSELECTWEEK (TEMPDATE)) {

Returndate = Tempdate;

Break;

}

}

Return Returndate;

}

/ ** Set whether it is selected for a week, 0 is Sunday, 1 is Monday .... 6 is Saturday * /

public

Void setSelectWeek

INT i,

Boolean b) {selectweek [i] = b;}

/ ** Judging whether a week is selected * /

public

Boolean IsselectWeek

INT i) {

Return SelectWeek [I];

/ ** Judge whether the day of the day is selected * /

public

Boolean isselectWeek (Date Date) {

IF (Date ==

NULL)

Return

False;

C.SetTime (date);

//Calendar.day_of_week: Sunday = 1, Saturday = 7 C.Get (Calendar.day_of_week)

Return isselectweek (C.GET (Calendar.day_of_week) - 1);

}

Public string gettimeplanstring () {

StringBuffer SB =

NEW STRINGBUFFER ("");

IF (SelectWeek [1]) sb.append ("Monday,");

IF (SelectWeek [2]) sb.append ("Tuesday,");

IF (SelectWeek [3]) sb.append ("Wednesday,");

IF (SelectWeek [4]) sb.append ("Thursday,");

IF (SelectWeek [5]) sb.append ("Friday,");

IF (SelectWeek [6]) sb.append ("Six,");

IF (SelectWeek [0]) SB.Append ("Sunday,");

Return "Weekly" Sb.toString () "Run";

}

}

Timertask's factory class. The advantage of another class of code that generates Timertask is that the level of the code is clear, and it is better to manage. Since Timertask contains several fields, a Timertask object is generated or has a certain complexity, build a factory class specifically generated Timertask so that we can lose a lot of trouble when generating a Timertask object. Of course, because of my job task, I only need a Timertask object enough, so I first wrote it directly in the code interface. Here is a Timertask object pool Tasks, which is a static variable so that you don't have to create a Timertask when getInstance. There is also a static variable, which is a global single example (which is the simplest single case mode), because the Timer can manage thousands of tasks, so the Timer object is enough.

Import java.util.hashmap;

Import java.util.timer;

public

Class taskentryfactory {

Private

Static

Final Hashmap Tasks =

New hashmap ();

Private

Static

FINAL TIMER TIMER =

New Timer ();

public

Static Taskentry GetInstance (Long Oid, String Name) {

IF (Tasks.Containskey (OID)) {

Return (Taskentry) Tasks.get (OID);

}

Else {

Taskentry entry =

NEW taskentry ();

Entry.SETOID (OID);

Entry.setName (Name);

Entry.settimer (Timer);

Entry.SetTimertask

NEW TIMERTASK_1 (Entry);

Tasks.Put (OID, Entry);

Return Entry;

}

}

}

Start and stop tasks, when the task setting interface (TaskListDialog.java "clicks OK processing. The writing of the interface is not within the scope of this article.

// Table of the Task Setting Interface Click "Confirm (OK)" button after the button

IF (Dialog.Open () == WINDOW.OK) {

IF (Taskentry.getState () == taskentry.task_start) {

Taskentry.taskstop (); // Stop the old stop

Taskentry.taskStart (); // Start new settings

}

IF (taskeTry.getState () == taskentry.task_stop)

Taskentry.taskstop ();

TV.Refresh (taskentry);

}

转载请注明原文地址:https://www.9cbs.com/read-123371.html

New Post(0)