在 Spring API 和 return 上设置一个计时器
Set a timer on a Spring API and return something
我有一个 Java 1.8 Spring 后端(Java 版本必须是 1.8),它管理一个加热器模拟器。例如,此后端会跟踪所需温度并确保加热器保持该温度。
现在我正在添加一种方法来设置温度和时间,并确保加热器在所需时间加热到所需温度。我正在考虑用多线程来实现它,但它似乎与我在 C# 中习惯的完全不同,我不确定它是否是最好的实现。
目前,如果有人向 API 发送请求以设置计时器,它会等待响应,直到请求超时或达到给定时间。同时 API 仍然可以被其他请求访问,但它仍然是一个糟糕的实现。
这是我当前尝试多线程的代码:
// in APIController.java, execution of timer logic starts here
@GetMapping("/timer")
public String timer(@RequestParam(value = "time", defaultValue = "ERROR") String time,
@RequestParam(value = "temperature", defaultValue = "15.0") String temperature) {
try {
LocalTime timer = LocalTime.parse(time);
double desiredTemperature = Double.parseDouble(temperature);
BackendController.getInstance().setTimer(timer, desiredTemperature);
return timer.toString() + " " + desiredTemperature; // Returns only when timer completes
} catch (DateTimeParseException | NumberFormatException e) {
return e.toString();
}
}
...
// in BackendController.java
// Singleton implementation
public void setTimer(LocalTime timer, double timerTemp) {
try {
Duration duration = Duration.between(LocalTime.now(), timer);
System.out.println("\n\nSetting a timer for " + timer.toString() + " with desired temperature " + timerTemp);
synchronized (singleton) { // Not sure what's the correct way to do this
singleton.wait(duration.toMillis());
desiredTemp = timerTemp;
System.out.println("\n\nSet desired temperature " + desiredTemp + " with timer trigger.");
}
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}
基本上我的问题归结为这两点:
- 我的思维过程正确吗?像这样的实现能满足我的需求吗?
- 如果不是,那会是什么?
经过一些工作和大量谷歌搜索后,我开始使用它了!阅读 https://jenkov.com/tutorials/java-concurrency/index.html 上的教程后,我对多线程的工作原理和实现方式有了更深入的了解。这是更新后的工作代码:
public void setTimer(LocalTime time, double timerTemp) {
Thread timer = new Thread(() -> {
try {
Duration duration = Duration.between(LocalTime.now(), time);
System.out.println("\n\nSetting a timer for " + time.toString() + " with desired temperature " + timerTemp);
Thread.sleep(duration.toMillis());
BackendController.desiredTemp = timerTemp;
System.out.println("\n\nSet desired temperature " + BackendController.desiredTemp + " with timer trigger.");
} catch (InterruptedException e) {
System.out.println(e);
}
});
timer.start();
}
我有一个 Java 1.8 Spring 后端(Java 版本必须是 1.8),它管理一个加热器模拟器。例如,此后端会跟踪所需温度并确保加热器保持该温度。
现在我正在添加一种方法来设置温度和时间,并确保加热器在所需时间加热到所需温度。我正在考虑用多线程来实现它,但它似乎与我在 C# 中习惯的完全不同,我不确定它是否是最好的实现。
目前,如果有人向 API 发送请求以设置计时器,它会等待响应,直到请求超时或达到给定时间。同时 API 仍然可以被其他请求访问,但它仍然是一个糟糕的实现。
这是我当前尝试多线程的代码:
// in APIController.java, execution of timer logic starts here
@GetMapping("/timer")
public String timer(@RequestParam(value = "time", defaultValue = "ERROR") String time,
@RequestParam(value = "temperature", defaultValue = "15.0") String temperature) {
try {
LocalTime timer = LocalTime.parse(time);
double desiredTemperature = Double.parseDouble(temperature);
BackendController.getInstance().setTimer(timer, desiredTemperature);
return timer.toString() + " " + desiredTemperature; // Returns only when timer completes
} catch (DateTimeParseException | NumberFormatException e) {
return e.toString();
}
}
...
// in BackendController.java
// Singleton implementation
public void setTimer(LocalTime timer, double timerTemp) {
try {
Duration duration = Duration.between(LocalTime.now(), timer);
System.out.println("\n\nSetting a timer for " + timer.toString() + " with desired temperature " + timerTemp);
synchronized (singleton) { // Not sure what's the correct way to do this
singleton.wait(duration.toMillis());
desiredTemp = timerTemp;
System.out.println("\n\nSet desired temperature " + desiredTemp + " with timer trigger.");
}
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}
基本上我的问题归结为这两点:
- 我的思维过程正确吗?像这样的实现能满足我的需求吗?
- 如果不是,那会是什么?
经过一些工作和大量谷歌搜索后,我开始使用它了!阅读 https://jenkov.com/tutorials/java-concurrency/index.html 上的教程后,我对多线程的工作原理和实现方式有了更深入的了解。这是更新后的工作代码:
public void setTimer(LocalTime time, double timerTemp) {
Thread timer = new Thread(() -> {
try {
Duration duration = Duration.between(LocalTime.now(), time);
System.out.println("\n\nSetting a timer for " + time.toString() + " with desired temperature " + timerTemp);
Thread.sleep(duration.toMillis());
BackendController.desiredTemp = timerTemp;
System.out.println("\n\nSet desired temperature " + BackendController.desiredTemp + " with timer trigger.");
} catch (InterruptedException e) {
System.out.println(e);
}
});
timer.start();
}