当前位置: 首页 > 知识库问答 >
问题:

如何每10秒执行一次?[副本]

柴琦
2023-03-14

我想每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());

共有2个答案

余弘新
2023-03-14

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。您可以选择scheduleatfixedrateschedulewithfixeddelay,因此阅读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来捕获任何意外的异常(可能还有错误)。异常/错误一直冒泡到计划的执行器服务,会导致服务静默停止,不再执行。

吕子真
2023-03-14

无法在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,再次处理程序,依此类推。