这是我的代码。
public class SetTimer extends Thread{
// set it on false from outside you want to stop
private boolean runSignal = true;
// sleep time
private final long SLEEP_TIME = 10*1000; //900 detik = 15 menit
PageReaderKontan pn = new PageReaderKontan();
PageReaderBisnis pb = new PageReaderBisnis();
FileListener fileListener = new FileListener();
Timer timer = new Timer();
boolean keep = true;
public void run(){
while (runSignal){
pn.run();
System.out.println("Kontan Finished.\n");
pb.run();
System.out.println("Bisnis Finished.\n");
fileListener.run();
doSleep(); //go to sleep
checkTime();
}
}
public void checkTime(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date alarmTime = calendar.getTime();
timer.schedule(new TimerTask() {
@Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
timer.cancel();
timer.purge();
return;
}
}, alarmTime);
System.out.println("Time checked.");
}
//sleep between listening folder iteration
public void doSleep(){
try{
System.out.println("I go to sleep for 10 seconds now...");
sleep(SLEEP_TIME);
}
catch (InterruptedException e){
System.out.println(e.getMessage());
}
}
//stop running this thread when application stops
public void stopRunning(){
System.out.println("Bye!");
this.runSignal = false;
}
}
在应用程序打印"编译在这里运行..."后,它返回以反复运行该线程。我的代码怎么错?请帮助我,我真的很难理解线程是如何工作的。非常感谢。 :)
编辑1 - 这是控制台输出。
Kontan完成。
Bisnis完成了。
我现在睡了10秒......
检查时间。
再见!
在这里编译运行......
Kontan完成。
Bisnis完成了。
我现在睡了10秒......
检查时间。
再见!
在这里编译运行......
...........
编辑2 - 更新 ...我使用System.exit()跳出无限循环并结束应用程序。
public void checkTime(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date alarmTime = calendar.getTime();
timer.schedule(new TimerTask() {
@Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
System.out.println("Application is closing...");
System.exit(0);
}
}, alarmTime);
System.out.println("Time checked.");
}
答案 0 :(得分:1)
请将runSignal布尔值声明为volatile。易失性保证读取变量的线程在读取之前看到另一个线程对其进行的更改。在您的情况下,看起来正在执行run的其他线程不会读取正在更改runSignal值的Timer线程,因此它不会停止。
private volatile boolean runSignal = true;
修改: - 强> 通过执行以下更改,您的代码可以正常工作。执行此更改的原因是为了避免尝试安排已取消的计时器的任何异常。
编写一个名为: -
的方法public void stopTimer() {
timer.cancel();
timer.purge();
}
从run方法中调用此方法,如下所示: -
public void run(){
while (runSignal){
pn.run();
System.out.println("Kontan Finished.\n");
pb.run();
System.out.println("Bisnis Finished.\n");
fileListener.run();
doSleep(); //go to sleep
checkTime();
}
stopTimer();
}
并从计时器计划方法中删除计时器取消,如下所示: -
timer.schedule(new TimerTask() {
@Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
return;
}
}, alarmTime);