我想每10秒执行一段代码。我在这个论坛上找到了一个例子,但我的实现有一些问题。
package robomow;
import robomow.SI7021;
import robomow.SGP30;
import com.pi4j.io.i2c.I2CFactory;
import java.io.IOException;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Environment {
long delay = 10000;
LoopTask task = new LoopTask();
Timer timer = new Timer("TaskName");
public void start() {
timer.cancel();
timer = new Timer("Environment");
SI7021 si7021 = new SI7021();
SGP30 sgp30 = new SGP30();
Date executionDate = new Date();
timer.scheduleAtFixedRate(task, executionDate, delay);
}
private class LoopTask extends TimerTask {
public void run() {
System.out.printf("Humidity = %.0f Temperature = %.2f \n", si7021.GetHumidity(), si7021.GetTemperature());
System.out.printf("eCO2 = %d ppm TVOC = %d \n", sgp30.getECO2(), sgp30.getTVOC());
}
}
public static void main(String[] args) throws InterruptedException,
IOException,
I2CFactory.UnsupportedBusNumberException {
Environment EnvironmentTask = new Environment();
SI7021 si7021 = new SI7021();
SGP30 sgp30 = new SGP30();
EnvironmentTask.start();
}
}
我得到这个错误,指向Si7021
:
Environment.java:28: error: cannot find symbol
System.out.printf("Humidity = %.0f Temperature = %.2f \n", si7021.GetHumidity(), si7021.GetTemperature());
iota的答案正确地解决了你的直接问题。但从更大的角度来看,你正在使用过时的类。使用executor服务和runnable的现代方法更加容易和简单。
在Java 5和更高版本中,定时器
和定时器任务
类被executor服务框架取代。
同样,可怕的date
类几年前就被JSR310中定义的现代java.time类所取代。具体替换为java.time.instant
。
让我们定义您的environment
类。该类监视对环境进行采样的两个设备,并在通过其report
方法进行询问时报告当前读数。
package work.basil.example;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.*;
public class Environment
{
private SI7021 si7021 = new Environment.SI7021();
private SGP30 sgp30 = new Environment.SGP30();
public void report ( )
{
System.out.println( "------------| Environment Report at " + Instant.now().truncatedTo( ChronoUnit.SECONDS ) + " |------------------------" );
System.out.printf( "Humidity = %.0f Temperature = %.2f \n" , si7021.getHumidity() , si7021.getTemperature() );
System.out.printf( "eCO2 = %d ppm TVOC = %d \n" , sgp30.getECO2() , sgp30.getTVOC() );
}
class SI7021
{
public float getHumidity ( )
{
return ThreadLocalRandom.current().nextFloat() * 100;
}
public float getTemperature ( )
{
return ThreadLocalRandom.current().nextFloat() * 100;
}
}
class SGP30
{
public int getECO2 ( )
{
return ThreadLocalRandom.current().nextInt( 1 , 100 );
}
public int getTVOC ( )
{
return ThreadLocalRandom.current().nextInt( 1 , 100 );
}
}
}
将任务定义为具有run
方法的runnable
对象。
使用lambda语法,这将是:
Runnable task = ( ) -> environment.report() ;
或者使用方法引用。
Runnable task = environment :: report ;
或者,如果您对现代语法不满意,可以使用匿名类。
Runnable task = new Runnable()
{
@Override
public void run ( )
{environment.report();}
};
scheduledexecutorservice
接口重复运行一个任务,即runnable
。您可以选择scheduleatfixedrate
或schedulewithfixeddelay
,因此阅读Javadoc以确定哪种节奏适合您的需要。
请确保优雅地关闭您的executor服务。否则,它的后台线程池可能会无限期地运行,就像一个僵尸。我们使用try-finally
来确保executor服务关闭。另外,将来当Project Loom到来时,executorservice
将是autocloseable
。然后我们就可以使用try-with-resources语法来实现更简单的关闭。
public static void main ( String[] args )
{
System.out.println( "INFO - Starting the scheduled executor service generating Environment reports. " + Instant.now() );
ScheduledExecutorService scheduledExecutorService = null;
try
{
Environment environment = new Environment();
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
Runnable task = environment :: report ;
scheduledExecutorService.scheduleAtFixedRate(
task , // Implements `Runnable`.
0 , // Initial delay.
Duration.ofSeconds( 10 ).toSeconds() , // Period
TimeUnit.SECONDS ) // Unit of time for both delay and period.
;
// … do other stuff
try { Thread.sleep( Duration.ofMinutes( 1 ).toMillis() ); } catch ( InterruptedException e ) { e.printStackTrace(); } // Give our demo a chance to run a while.
System.out.println( "INFO - Will shutdown the scheduled executor service generating Environment reports. " + Instant.now() );
}
finally
{
if ( Objects.nonNull( scheduledExecutorService ) ) { scheduledExecutorService.shutdown(); }
}
}
运行时:
INFO - Starting the scheduled executor service generating Environment reports. 2021-01-04T07:46:54.494330Z
------------| Environment Report at 2021-01-04T07:46:54Z |------------------------
Humidity = 95 Temperature = 40.71
eCO2 = 99 ppm TVOC = 1
------------| Environment Report at 2021-01-04T07:47:04Z |------------------------
Humidity = 72 Temperature = 92.15
eCO2 = 25 ppm TVOC = 42
------------| Environment Report at 2021-01-04T07:47:14Z |------------------------
Humidity = 52 Temperature = 94.01
eCO2 = 85 ppm TVOC = 89
------------| Environment Report at 2021-01-04T07:47:24Z |------------------------
Humidity = 80 Temperature = 1.60
eCO2 = 10 ppm TVOC = 78
------------| Environment Report at 2021-01-04T07:47:34Z |------------------------
Humidity = 64 Temperature = 44.97
eCO2 = 50 ppm TVOC = 40
------------| Environment Report at 2021-01-04T07:47:44Z |------------------------
Humidity = 1 Temperature = 31.63
eCO2 = 20 ppm TVOC = 69
------------| Environment Report at 2021-01-04T07:47:54Z |------------------------
Humidity = 30 Temperature = 26.88
eCO2 = 2 ppm TVOC = 86
INFO - Will shutdown the scheduled executor service generating Environment reports. 2021-01-04T07:47:54.516543Z
在实际工作中,在runnable
的内部使用try-catch来捕获任何意外的异常(可能还有错误)。异常/错误一直冒泡到计划的执行器服务,会导致服务静默停止,不再执行。
无法在TimerTask
中访问您声明的变量;您应该考虑将它们移到类中。
private class LoopTask extends TimerTask {
SI7021 si7021;
SGP30 sgp30;
public LoopTask() {
try {
si7021 = new SI7021();
sgp30 = new SGP30();
} catch(Exception e){
//handle exception
}
}
public void run() {
System.out.printf("Humidity = %.0f Temperature = %.2f \n", si7021.GetHumidity(), si7021.GetTemperature());
System.out.printf("eCO2 = %d ppm TVOC = %d \n", sgp30.getECO2(), sgp30.getTVOC());
}
}
问题内容: 我有一个ajax调用到一个php文件。我正在收到结果。现在,我正在研究是否有可能使ajax请求每1秒自动执行一次。我将结果发布到名为的输入字段中。如何每三秒钟执行一次ajax调用而不必调用该函数? 问题答案: 您可能要考虑的是服务器发送事件(SSE) 这是一种HTML5技术,JavaScript可以通过该技术“ 长期轮询 ”服务器端点(您的PHP文件)以查看是否发生了任何更改。长轮询基
问题内容: 请查找每10秒钟重复一次的更新代码。但是,问题在于它每10秒在屏幕上创建一个新的GUI,而不是仅每10秒更新一次数据。请您指教 问题答案: 您只有一门课,Learningfromscrach。在其中,您具有主要功能。在主要功能内,您将创建 另一个 Learningfromscrach 实例 ,该 实例 现在传递给计时器,每10秒运行一次。当它在10秒内运行时,它会创建另一个Learni
问题内容: 我想在单击按钮时从GUIinput获取数据,我编写此代码以获取数据,然后进入无限循环 问题答案: 我想单击按钮时从GUIinput获取数据 您正在上使用,这将阻止GUI响应事件,直到循环完成为止。 不要在EDT上使用Thread.sleep(…)! 有两种常见的解决方案: 使用Swing计时器每10秒安排一次事件。 使用单独的线程。然后,在此线程中,可以使用Thread.sleep()
问题内容: 抱歉,我有点菜鸟,我只想知道我如何让此javascript每秒钟运行一次? 源代码: 问题答案: 使用setInterval()每x毫秒运行一段代码。 您可以将要每秒运行的代码包装到一个名为的函数中。 因此它将是: 要停止它,可以运行:
问题内容: 我想知道如何每x秒重绘和更新JPanel的背景…这是我的代码: 我的代码有2个问题:1-JPanel根本没有被绘制。2-第一张可以打印,然后每次打印数量增加一倍。有什么建议吗?先感谢您 更新:我以这种方式解决了这个问题: 更新2: 问题答案: 使用Swing计时器,
问题内容: 我需要每10秒从服务器收到一个状态。 我试图通过服务发送一个http请求来做到这一点。 问题是我的代码只能执行一次。 这是我的服务代码: 谢谢很多阿维 问题答案: 将处理程序放入onPostExecute中以在10秒后发送http请求 10秒后,将再次执行doInBackground,然后再次执行onPostExecute,再次处理程序,依此类推。