java启用一个倒计时任务

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java启用一个倒计时任务相关的知识,希望对你有一定的参考价值。

启用一个连接,把连接存放到一个map中,这个时候没有关闭连接,做一个5秒后关闭连接的机制。(如果调用者在倒计时范围内调用了连接,则重新计数倒计时)目的是判断是否有在调用这个连接,如果没有就关闭。

用java如何创建一个定时器,5秒后打印一句话;(括弧不是每隔5秒,是5秒后执行一次,就执行一次)这时又来一个方法调用这个定时器,如果判断定时器再倒计时范围内中断倒计时重新倒计时,如果定时器没有执行,启用一个5秒后执行的定时器任务

你看一下这个吧.用线程来检查超时时间.

----------------------------------------------------------------------
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.SwingConstants;

public class DemoApp extends JFrame implements ActionListener, Runnable
private JTextField textField;
private int seconds = 0;
// 默认超时时间是10秒
private int time = 10;
private JLabel showTime;
private JButton btnStart;

public DemoApp()

getContentPane().setLayout(null);

JLabel label = new JLabel("设置时间");
label.setBounds(10, 10, 64, 15);
getContentPane().add(label);

textField = new JTextField();
textField.setBounds(84, 7, 35, 21);
getContentPane().add(textField);
textField.setColumns(10);

JLabel label_1 = new JLabel("秒");
label_1.setBounds(129, 10, 25, 15);
getContentPane().add(label_1);

btnStart = new JButton("开始");
btnStart.setBounds(164, 6, 64, 23);
btnStart.addActionListener(this);
btnStart.setActionCommand("S");
getContentPane().add(btnStart);

JLabel label_2 = new JLabel("计时");
label_2.setBounds(10, 38, 54, 15);
getContentPane().add(label_2);

showTime = new JLabel("0");
showTime.setHorizontalAlignment(SwingConstants.RIGHT);
showTime.setBounds(84, 38, 35, 15);
getContentPane().add(showTime);

JButton button = new JButton("模拟使用连接");
button.setBounds(168, 39, 116, 23);
button.addActionListener(this);
button.setActionCommand("M");
getContentPane().add(button);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setSize(300, 150);
setLocationRelativeTo(null);
setVisible(true);


public static void main(String[] args)
new DemoApp();


public void actionPerformed(ActionEvent e)
if ("S".equals(e.getActionCommand()))

try
time = Integer.parseInt(textField.getText());
catch (Exception ex)


new Thread(this).start();
// 按钮不可用。
btnStart.setEnabled(false);
textField.setEditable(false);

if ("M".equals(e.getActionCommand()))
seconds = 0;



public void run()
while (true)
try
showTime.setText("" + seconds);
// 检查是否超时
if (seconds == time)
// 超时后可重新设置时间
btnStart.setEnabled(true);
textField.setEditable(true);
break;

seconds++;
// 休眠时间设为一秒,如果总的超时时间很长的话,可以多设置一些
// 比如30秒超时,可以设置为5秒一检查
Thread.sleep(1000);
catch (Exception e)




参考技术A 用延时 Thread.sleep、或Timer+TimeTask 简单用法如下,详细的看API

import java.util.Timer;
import java.util.TimerTask;

/**
* Simple demo that uses java.util.Timer to schedule a task to execute once 5 seconds have passed.
*/

public class Reminder
Timer timer;

public Reminder(int seconds)
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);


class RemindTask extends TimerTask
public void run()
System.out.println("Time's up!");
timer.cancel(); //Terminate the timer thread



public static void main(String args[])
new Reminder(5);
System.out.println("Task scheduled.");

如何在 Java 中计时方法的执行?

【中文标题】如何在 Java 中计时方法的执行?【英文标题】:How do I time a method's execution in Java? 【发布时间】:2010-09-15 20:40:14 【问题描述】:
    如何获取方法的执行时间? 是否有一个Timer 实用程序类用于计时任务需要多长时间等?

Google 上的大多数搜索都返回了用于安排线程和任务的计时器的结果,这不是我想要的。

【问题讨论】:

JAMon API 是一个免费、简单、高性能、线程安全的 Java API,它允许开发人员轻松监控生产应用程序的性能和可扩展性。 JAMon 跟踪命中、执行时间(总、平均、最小值、最大值、标准差)等。 http://jamonapi.sourceforge.net/ 下载:http://sourceforge.net/project/showfiles.php?group_id=96550 您可能还想查看Apache Commons Lang StopWatch 类。一个简单但有用的实用程序类。 后期类似问题:How do I write a correct micro-benchmark in Java? 是的,秒表非常适合。 Java 8 使用 Instant 类:***.com/a/30975902/1216775 【参考方案1】:

如果只是想知道时间,您可以尝试这种方式。

long startTime = System.currentTimeMillis();
//@ Method call
System.out.println("Total time [ms]: " + (System.currentTimeMillis() - startTime));    

【讨论】:

【参考方案2】:

在 Java 8 中引入了一个名为 Instant 的新类。根据文档:

Instant 表示时间线上一纳秒的开始。这 类对于生成表示机器时间的时间戳很有用。 瞬间的范围需要存储一个大于a的数字 长。为了实现这一点,该类存储了一个长表示 epoch-seconds 和一个表示 nanosecond-of-second 的 int,这将 始终介于 0 和 999,999,999 之间。测量纪元秒数 从 1970-01-01T00:00:00Z 的标准 Java 时代开始 在 epoch 之后有正值,并且更早的时刻有 负值。对于纪元秒和纳秒部分,a 在时间线上,较大的值总是比较小的值晚。

这可以用作:

Instant start = Instant.now();
try 
    Thread.sleep(7000);
 catch (InterruptedException e) 
    e.printStackTrace();

Instant end = Instant.now();
System.out.println(Duration.between(start, end));

它打印PT7.001S

【讨论】:

【参考方案3】:

如果java有更好的功能支持就好了,这样需要度量的动作可以被包裹到一个块中:

measure 
   // your operation here

在java中这可以通过匿名函数来完成,看起来太冗长了

public interface Timer 
    void wrap();



public class Logger 

    public static void logTime(Timer timer) 
        long start = System.currentTimeMillis();
        timer.wrap();
        System.out.println("" + (System.currentTimeMillis() - start) + "ms");
    

    public static void main(String a[]) 
        Logger.logTime(new Timer() 
            public void wrap() 
                // Your method here
                timeConsumingOperation();
            
        );

    

    public static void timeConsumingOperation() 
        for (int i = 0; i<=10000; i++) 
           System.out.println("i=" +i);
        
    

【讨论】:

可以通过使用 Java 8 的 lambda 表达式来清理。 drdobbs.com/jvm/lambda-expressions-in-java-8/240166764?pgno=2 确实,由于 Java 8,java.lang.Runnable@FunctionalInterface,这意味着您可以将 lambda 表达式传递给任何以 Runnable 作为参数的方法。您的timeThisCode(Runnable r) 可以简单地返回毫秒/纳米或更精细的经过时间的表示。【参考方案4】:

这里是漂亮的打印字符串准备好格式化的秒数,类似于谷歌搜索时间:

        long startTime = System.nanoTime();
        //  ... methodToTime();
        long endTime = System.nanoTime();
        long duration = (endTime - startTime);
        long seconds = (duration / 1000) % 60;
        // formatedSeconds = (0.xy seconds)
        String formatedSeconds = String.format("(0.%d seconds)", seconds);
        System.out.println("formatedSeconds = "+ formatedSeconds);
        // i.e actual formatedSeconds = (0.52 seconds)

【讨论】:

nonoTime 不是 /1000 秒。你的数学假设 getTime 是毫秒。最好做 /1e6 以获得毫秒。【参考方案5】:

我实现了一个简单的计时器,我认为它真的很有用:

public class Timer
    private static long start_time;

    public static double tic()
        return start_time = System.nanoTime();
    

    public static double toc()
        return (System.nanoTime()-start_time)/1000000000.0;
    


这样你就可以为一个或多个动作计时:

Timer.tic();
// Code 1
System.out.println("Code 1 runtime: "+Timer.toc()+" seconds.");
// Code 2
System.out.println("(Code 1 + Code 2) runtime: "+Timer.toc()+"seconds");
Timer.tic();
// Code 3
System.out.println("Code 3 runtime: "+Timer.toc()+" seconds.");

【讨论】:

【参考方案6】:

您可以使用javaagent来修改java类字节,动态添加监控代码。github上有一些开源工具可以为您做到这一点。 如果你想自己做,只需要实现javaagent,使用javassist修改你要监控的方法,在你的方法返回之前的监控代码。很干净并且您可以监控甚至没有源代码的系统。

【讨论】:

【参考方案7】:

System.nanoTime() 是一个非常精确的系统实用程序,用于测量执行时间。但请注意,如果您在抢占式调度程序模式(默认)下运行,此实用程序实际上测量的是挂钟时间而不是 CPU 时间。因此,您可能会注意到每次运行的执行时间值不同,具体取决于系统负载。如果您寻找 CPU 时间,我认为以实时模式运行您的程序就可以了。你必须使用 RT linux。链接:Real-time programming with Linux

【讨论】:

【参考方案8】:

在 java ee 中对我有用的策略是:

    @AroundInvoke注解的方法创建一个类;

    @Singleton
    public class TimedInterceptor implements Serializable 
    
        @AroundInvoke
        public Object logMethod(InvocationContext ic) throws Exception 
            Date start = new Date();
            Object result = ic.proceed();
            Date end = new Date();
            System.out.println("time: " + (end.getTime - start.getTime()));
            return result;
        
    
    

    注释你要监控的方法:

    @Interceptors(TimedInterceptor.class)
    public void onMessage(final Message message)  ... 
    

我希望这会有所帮助。

【讨论】:

【参考方案9】:

对于 java 8+,另一种可能的解决方案(更通用,func 样式且没有方面)可能是创建一些实用方法,接受代码作为参数

public static <T> T timed (String description, Consumer<String> out, Supplier<T> code) 
    final LocalDateTime start = LocalDateTime.now ();
    T res = code.get ();
    final long execTime = Duration.between (start, LocalDateTime.now ()).toMillis ();
    out.accept (String.format ("%s: %d ms", description, execTime));
    return res;

调用代码可能是这样的:

public static void main (String[] args) throws InterruptedException 
    timed ("Simple example", System.out::println, Timing::myCode);


public static Object myCode () 
    try 
        Thread.sleep (1500);
     catch (InterruptedException e) 
        e.printStackTrace ();
    
    return null;

【讨论】:

【参考方案10】:

也可以实现 Timer 接口并在你的类的任何方法上执行

import java.util.function.*;

public interface Timer 

    default void timeIt(Runnable r) 
        timeIt(() ->  r.run(); return 0;);
    

    default <S,T> T timeIt(Function<S,T> fun, S arg) 
        long start = System.nanoTime();
        T result = fun.apply(arg);
        long stop = System.nanoTime();
        System.out.println("Time: " + (stop-start)/1000000.0 + " msec");
        return result;
    

    default <T> T timeIt(Supplier<T> s) 
        return timeIt(obj -> s.get(), null);
    

用法:

class MyClass implements Timer ..

timeIt(this::myFunction); 

【讨论】:

【参考方案11】:

这里有很多有效的答案,所有这些都是在方法中实现的。为了制作一个通用的计时方法,我通常有一个 Timing 类,包含以下内容。

public record TimedResult<T>(T result, Duration duration) 

public static Duration time(Runnable r) 
    var s = Instant.now();
    r.run();
    var dur = Duration.between(s, Instant.now());
    return dur;


public static <T> TimedResult<T> time(Callable<T> r) throws Exception 
    var s = Instant.now();
    T res = r.call();
    var dur = Duration.between(s, Instant.now());
    return new TimedResult<>(res, dur);

这足以传递Runnable 或Callable。

Duration result = Timing.time(() -> 
    // do some work.
);

TimedResult<String> result = Timing.time(() -> 
    // do some work.
    return "answer";
);

Duration timeTaken = result.duration();
String answer = result.result();

【讨论】:

【参考方案12】:

纯Java SE代码,无需添加依赖,使用TimeTracedExecuter

public static void main(String[] args) 

    Integer square = new TimeTracedExecutor<>(Main::calculateSquare)
                .executeWithInput("calculate square of num",5,logger);


public static int calculateSquare(int num)
    return num*num;

会产生这样的结果:

INFO: It took 3 milliseconds to calculate square of num

自定义可重用类:TimeTracedExecutor

import java.text.NumberFormat;
import java.time.Duration;
import java.time.Instant;
import java.util.function.Function;
import java.util.logging.Logger;

public class TimeTracedExecutor<T,R> 
    Function<T,R> methodToExecute;

    public TimeTracedExecutor(Function<T, R> methodToExecute) 
        this.methodToExecute = methodToExecute;
    

    public R executeWithInput(String taskDescription, T t, Logger logger)
        Instant start = Instant.now();
        R r= methodToExecute.apply(t);
        Instant finish = Instant.now();
        String format = "It took %s milliseconds to "+taskDescription;
        String elapsedTime = NumberFormat.getNumberInstance().format(Duration.between(start, finish).toMillis());
        logger.info(String.format(format, elapsedTime));
        return r;
    

【讨论】:

以上是关于java启用一个倒计时任务的主要内容,如果未能解决你的问题,请参考以下文章

java计时器

java线程怎么做个时间倒计时

如何在 Java 中计时方法的执行?

等待计时器在 Java 中完成

Quartz+JAVA+Servlet实现任务调度系统(简洁)

Java Swing的计时器组件Timer