我正在尝试将当前时间与HashMap中的值进行比较,以打印通知消息(如警报)。但是,当当前时间达到等于HashMap中的值的时间时,它不会打印。这是因为containsValue方法没有足够的时间来迭代HashMap或其他原因吗?这是我的相关代码:
private SimpleDateFormat timeFormat = new SimpleDateFormat("kk:mm:ss");
@Override
public void run() {
while (true) {
String currentTime = getCurrentTime();
if (callLog.containsValue(currentTime)) {
System.out.println("it works!");
}
}
public String getCurrentTime() {
Date time = Calendar.getInstance().getTime();
String currentTIme = timeFormat.format(time);
return currentTIme;
}
编辑:好的,我通过一些调整找出了问题所在。如果我在我设置闹钟的确切时刻运行程序,我的if检查是否有效。如果我等待闹钟响起(例如程序运行后2分钟),则不会发送消息。修改后的代码:
private HashMap<Integer, String> callLog;
private SimpleDateFormat timeFormat = new SimpleDateFormat("kk:mm:ss");
private String wakeUpMessage = "This is your automatic wake up call for room number: ";
private String nextCall;
private Thread thread;
public HotelSystem() {
callLog = new LinkedHashMap<Integer, String>();
this.thread = new Thread(this);
this.thread.start();
setAlarmTime(4, "20:45:00");
}
@Override
public void run() {
while (true) {
if (callLog.containsValue(getCurrentTime())) {
System.out.println(getCurrentTime());
sendAlarmCall(4);
}
}
}
// sends a generic alarm call message followed by the room number
public void sendAlarmCall(int roomNumber) {
System.out.println(wakeUpMessage + roomNumber);
}
public String getCurrentTime() {
Date time = Calendar.getInstance().getTime();
String currentTIme = timeFormat.format(time);
return currentTIme;
}
public void setAlarmTime(int roomNumber, String time) {
Date alarmDate;
try {
alarmDate = timeFormat.parse(time);
String alarmTime = timeFormat.format(alarmDate);
callLog.put(roomNumber, alarmTime);
System.out.println("You entered room number: " + roomNumber + " and wake up time of: " + alarmTime);
} catch (ParseException e) {
System.out.println("Please ensure you seperate the time with colons eg 07:30:00.");
}
}
编辑2:好的,现在真的很奇怪。它适用于我放入的所有内容,除非秒等于00.我不知道它为什么会这样做。
答案 0 :(得分:2)
我很确定它从来没有&#34;时间等于HashMap中的值#34;正如你所说。如果您的标准输出正在运行(System.out要写入的控制台),则if条件永远不会被评估为true。
方法containsValue肯定有足够的时间进行评估。除非你打断整个线程,否则不可能在其评估过程中中断某个方法(至少在你的情况下),除非你打断整个线程。
寻找可能的解决方案:
a)在调试模式下,检查hashmap中的字符串值类型以及currentTime字符串的外观。可能存在格式问题。从您的代码中,无法分辨callLog包含的值。
b)不要将时间与字符串进行比较。我知道你需要在几秒钟内达到分辨率(毫秒或纳米可能导致问题&#34;达到等于时间&#34;),但是通过将Date转换为字符串这样做是资源匮乏和缓慢的方式。你实际可以做的是创建自己的类,例如ScheduleTime包含很少的原始属性(小时,分钟,秒)并覆盖hashCode()和equals()方法。有很多关于如何正确执行此操作的教程,非常简单。
c) run()方法不经常调用。如果您希望在几秒钟内获得时间分辨率,请确保每秒触发此方法。
还考虑使用Thread.sleep()而不是一遍又一遍地创建和销毁线程。但是这样,你必须引用你的hashmap作为线程对象的属性。但是HashMap不是ThreadSafe,为了线程安全,有ConcurrentHashMap。但这只是一个推荐。
答案 1 :(得分:1)
如果您的程序一直在运行,使用ScheduledThreadPoolExecutor或只是java.util.Timer可以帮助您。它们允许存储在没有CPU循环的情况下调用的定时器。
如果您想使用闹钟时间自己制作一个TreeMap,那么整数键可能是一个好的开始。