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启用一个倒计时任务的主要内容,如果未能解决你的问题,请参考以下文章