需要修复我的Java计时器代码吗
任务-在一天中的指定时间打开和关闭灯泡。我需要知道如何根据下面给出的信息修复我的代码。我还需要知道我是否正确使用了timer类,也就是说,我的代码设计是否正确?代码可能会工作,但可能是糟糕的设计,这将在以后导致问题。我不想那样 输出是(这不是我真正想要的输出:()- 期望输出-需要修复我的Java计时器代码吗,java,timertask,Java,Timertask,任务-在一天中的指定时间打开和关闭灯泡。我需要知道如何根据下面给出的信息修复我的代码。我还需要知道我是否正确使用了timer类,也就是说,我的代码设计是否正确?代码可能会工作,但可能是糟糕的设计,这将在以后导致问题。我不想那样 输出是(这不是我真正想要的输出:()- 期望输出- This is the main program Current time is - xxx Future time is - xxx+5sec Future time is - xxx+10sec Bulb B1 is
This is the main program
Current time is - xxx
Future time is - xxx+5sec
Future time is - xxx+10sec
Bulb B1 is ON //first on
Bulb B1 is OFF //then off
Main program ends//This should always be in the end.
我如何修复下面的代码以获得我想要的
灯泡
等级
class Bulb {
private boolean state = false;//On or off
private String name;
Bulb(String name){
this.name = name;
}
public void setState(boolean state){
this.state = state;
if(this.state == true){
System.out.println("Bulb " + name + " is ON");
}else{
System.out.println("Bulb " + name + " is OFF");
}
}
public boolean getState(){
return this.state;
}
}
BulbJob
类,它是一个TimerTask
import java.util.*;
class BulbJob extends TimerTask{
private Bulb bulbToHandle;
private boolean setBulbStateEqualTo;
BulbJob(Bulb toHandle){
this.bulbToHandle = toHandle;
}
//NOTE: Must be called before run(), otherwise default value is used
public void setBulbStateEqualTo(boolean setBulbStateEqualTo){
this.setBulbStateEqualTo = setBulbStateEqualTo;
}
//NOTE: call run() only before calling above method
public void run(){
this.bulbToHandle.setState(setBulbStateEqualTo);//Set on or off
}
}
BulbScheduler
class-此计划在灯泡打开或关闭时进行
import java.util.*;
@SuppressWarnings( "deprecation" )
class BulbScheduler {
public static void main(String args[]) throws InterruptedException{
System.out.println("This is the main program");
Timer time = new Timer();
Bulb b1 = new Bulb("B1");
BulbJob bj = new BulbJob(b1);
bj.setBulbStateEqualTo(true);//Task - Turn bulb on at time = afterCurrent
Date current = new Date();//Get current time and execute job ten seconds after this time
Date afterCurrent = (Date) current.clone();
System.out.println("Current time is - " + current);
int currentSecs = current.getSeconds();
int offset = 5;//number of seconds
afterCurrent.setSeconds(currentSecs + offset);
System.out.println("Future time is - " + afterCurrent);
time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent
//Now turn the bulb off at new time = newest afterTime
afterCurrent.setSeconds(currentSecs + 2 * offset);
System.out.println("Future time is - " + afterCurrent);
bj.setBulbStateEqualTo(false);//Task - Now turn the bulb off at time = afterCurrent
System.out.println("Main program ends");
}
}
本节:
time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent
//Now turn the bulb off at new time = newest afterTime
afterCurrent.setSeconds(currentSecs + 2 * offset);
仅计划一项任务。如果需要计划两次,请明确执行以下操作:
time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent
//Now turn the bulb off at new time = newest afterTime
afterCurrent.setSeconds(currentSecs + 2 * offset);
time.schedule(bj, afterCurrent);//Schedule job "bj" at time = afterCurrent
此外,这一行:
bj.setBulbStateEqualTo(false);
在主线程中执行,因此它将在两个任务之前执行。您应该计划该语句在两个任务之间运行。代码已修复,但此版本最终无法退出main-
import java.util.*;
@SuppressWarnings( "deprecation" )
class BulbScheduler {
public static void main(String args[]) throws InterruptedException{
System.out.println("This is the main program");
Timer timeOn = new Timer();
Timer timeOff = new Timer();
Bulb b1 = new Bulb("B1");
BulbJob bjOn = new BulbJob(b1);
BulbJob bjOff = new BulbJob(b1);
bjOn.setBulbStateEqualTo(true);//Task - Turn bulb on
bjOff.setBulbStateEqualTo(false);//Task - Then turn the bulb off later
Date current = new Date();//Get current time and execute job ten seconds after this time
Date afterCurrent = (Date) current.clone();
System.out.println("Current time is - " + current);
int currentSecs = current.getSeconds();
int offset = 3;//number of seconds
afterCurrent.setSeconds(currentSecs + offset);
System.out.println("Future time is - " + afterCurrent);
timeOn.schedule(bjOn, afterCurrent);//Schedule job "bj" at time = afterCurrent
//Now turn the bulb off at new time = latest afterCurrent
afterCurrent.setSeconds(currentSecs + 2 * offset);
System.out.println("Future time is - " + afterCurrent);
timeOff.schedule(bjOff, afterCurrent);
System.out.println("Main program ends");
}
}
您没有正确设置时间。需要使用GreogarianCalendar 使用java.util.Date,但不能使用其setSeconds读取Javadoc,这很好,会有很大帮助。public void setSeconds(int seconds) 不推荐使用。从JDK版本1.1开始,替换为Calendar.set(Calendar.SECOND,int seconds)。 将此日期的秒数设置为指定值。修改此日期对象,使其表示指定秒数内的时间点,年、月、日期、小时和分钟与以前相同,在本地时区中进行解释 您需要使用java.util.GregorianCalendar#add(Calendar.SECOND,howManySeconds) 然后使用getDate()获取日期对象并将其发送给计时器
在日期上调用setSecond不会更改其他字段。请参阅Calendar.add and roll的java文档,并查看inro类中的规则。还可以使用计时器对象的计划(TimerTask任务,长延迟) 计划在指定延迟(毫秒)后执行指定的任务。 修改代码-
import java.util.*;
class BulbScheduler {
private static java.text.SimpleDateFormat sdf1 = new java.text.SimpleDateFormat ("yy MM dd HH mm ss");
//helper
static String formatDate(Date d){
return sdf1.format(d);
}
public static void main(String args[]) throws InterruptedException{
System.out.println("This is the main method");
java.util.GregorianCalendar cal = new java.util.GregorianCalendar();
Bulb b1 = new Bulb("bulb 1", false);
Bulb b2 = new Bulb("bulb 2", false);
System.out.println("Time now " + formatDate(cal.getTime()));
Timer timer = new Timer("bulbs");
BulbJob b1On = new BulbJob(b1, true);
BulbJob b1Off = new BulbJob(b1, false);
BulbJob b2On = new BulbJob(b2, true);
BulbJob b2Off = new BulbJob(b2, false);
timer.schedule(b1On, 3 * 1000);//after 3 seconds
timer.schedule(b2On, 7 * 1000);//after 4 seconds
timer.schedule(b1Off, 6 * 1000);//after 6 seconds; before b2 on
b1On = new BulbJob(b1, true);
timer.schedule(b1On, 9 * 1000);
//if you want main to wait need to add code here to make it wait,
// but even if does the JVM wont exit. Its just a method. The JVM exits when all non daemon threads are done
// or System.exit is called
System.out.println("This is the main method ending; but other threads might be running ...");
//main thread JVM waits for all other non dameons to end
}
}
改变了BulbJob
导入java.util.*
类BulbJob扩展了TimerTask{
private Bulb bulbToHandle;
private boolean bulbNewState;//dont start propert names with set
//why a seperate property when we need to set the new state everytime and cannot reuse jobs?
BulbJob(Bulb toHandle, boolean newState){
this.bulbToHandle = toHandle;
bulbNewState= newState;
}
public void run(){
this.bulbToHandle.setState(bulbNewState);//Set on or off
}
}
班级灯泡。。。
公共无效设置状态(布尔状态){
this.state=状态;
System.out.println(“bull”+name+“是”+(状态?“开”):“关”)+“在”+BulbScheduler.formatDate(new java.util.Date());//如果还可以的话
}+1选择
TimerTask
而不是普通的线程sleep()
@asgs-如何使“主程序结束”只在执行完所有操作后才出现?由于主线程不依赖于您的作业,恐怕您需要重新设计,以便使用线程的加入()
方法等待TimerTask完成。@asgs-那么,BulbJob扩展了线程???但是,我将丢失所有TimerTask功能。如何修复此问题(@asgs-还有,这就是我想做的-在currentTime+5秒打开灯泡。然后,在currentTime+10秒关闭同一个灯泡。我是否必须创建新的灯泡或计时器来关闭它?同样,这也是我想做的-在currentTime+5秒打开灯泡。然后,在currentTime+10秒关闭同一个灯泡。我是否必须创建新的灯泡bJob或Timer关闭它?创建3个任务:turnBulbOn、turnBulbOff、ExitProgram,完成这些任务并一个接一个地安排它们。你只需要一个计时器。好了。使用自定义消息作为单独的TimerTask
退出程序是最好的选择。@assylias-我该如何完成ExitProgram任务?我还需要做其他事情吗s按照计划工作。我添加了修改后的代码作为我的答案。只是部分正确。设置秒不是办法。尝试从2:59:59开始的日期时间不会到3:00:00。查看其他答案,使用Calendar.roll查看java.util.date#SetSecondy的api javadoc您正在主线程中打印主程序结束
,它将立即执行如果你想让它延迟,你需要用它做一个任务,并在关掉灯泡后运行。@assylias-好的。我可以做EnProgram任务。但是,我只能在bjOff之后运行它。因此,我必须跟踪所有的计时,这非常不方便。不幸的是,没有join()TimerTask的方法,即仅在task2完成后完成task1。您也可以使用阻止机制,例如倒计时闩锁。这是一个错误的实现。设置秒不是最好的方法。请尝试将日期时间从2:59:59改为3:00:00。若要查看其他答案,请使用Calendar.roll
private Bulb bulbToHandle;
private boolean bulbNewState;//dont start propert names with set
//why a seperate property when we need to set the new state everytime and cannot reuse jobs?
BulbJob(Bulb toHandle, boolean newState){
this.bulbToHandle = toHandle;
bulbNewState= newState;
}
public void run(){
this.bulbToHandle.setState(bulbNewState);//Set on or off
}