在一段时间内运行代码的更好方法 [英] A better way to run code for a period of time

查看:113
本文介绍了在一段时间内运行代码的更好方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在预定义的时间内运行一些代码,当时间到了需要停止时。目前我正在使用TimerTask来允许代码执行一段时间,但这会导致代码创建无穷无尽的线程,而这只是效率不高。还有更好的选择吗?

I need to run some code for a predefined length of time, when the time is up it needs to stop. Currently I am using a TimerTask to allow the code to execute for a set amount of time but this is causing endless threads to be created by the code and is just simply not efficient. Is there a better alternative?

当前代码;

// Calculate the new lines to draw 
            Timer timer3 = new Timer();
            timer3.schedule(new TimerTask(){
                public void run(){
                    ArrayList<String> Coords = new ArrayList<String>();
                    int x = Float.valueOf(lastFour[0]).intValue();
                    int y = Float.valueOf(lastFour[1]).intValue();
                    int x1 = Float.valueOf(lastFour[2]).intValue();
                    int y1 = Float.valueOf(lastFour[3]).intValue();
                    //Could be the wrong way round (x1,y1,x,y)?
                    Coords = CoordFiller.coordFillCalc(x, y, x1, y1);
                    String newCoOrds = "";
                    for (int j = 0; j < Coords.size(); j++)
                    {
                        newCoOrds += Coords.get(j) + " ";
                    }
                    newCoOrds.trim();
                    ClientStorage.storeAmmendedMotion(newCoOrds);

                }

            }
            ,time);


推荐答案

如果您使用的是Java5或更高版本,请考虑 的ScheduledThreadPoolExecutor Future 。使用前者,您可以安排在指定的延迟之后或以指定的时间间隔运行任务,从而更可靠地接管 Timer 的角色。

If you are using Java5 or later, consider ScheduledThreadPoolExecutor and Future. With the former, you can schedule tasks to be run after a specified delay, or at specified intervals, thus it takes over the role of Timer, just more reliably.


计时器工具管理延迟执行(在100中运行此任务ms)和周期性(每10毫秒运行一次该任务)任务。但是,计时器有一些缺点,应该将 ScheduledThreadPoolExecutor 视为其替代品。 [...]

The Timer facility manages the execution of deferred ("run this task in 100 ms") and periodic ("run this task every 10 ms") tasks. However, Timer has some drawbacks, and ScheduledThreadPoolExecutor should be thought of as its replacement. [...]

A 计时器只创建一个用于执行计时器任务的线程。如果计时器任务运行时间太长,其他 TimerTask 的计时准确度可能会受到影响。如果定期运行的 TimerTask 计划每10毫秒运行一次,而另一个 TimerTask 运行需要40毫秒,则重复执行的任务要么(取决于它是按固定速率安排还是固定延迟)在长时间运行的任务完成后快速连续调用四次,或完全错过四次调用。计划的线程池通过允许您提供多个线程来执行延迟和定期任务来解决此限制。

A Timer creates only a single thread for executing timer tasks. If a timer task takes too long to run, the timing accuracy of other TimerTasks can suffer. If a recurring TimerTask is scheduled to run every 10 ms and another TimerTask takes 40 ms to run, the recurring task either (depending on whether it was scheduled at fixed rate or fixed delay) gets called four times in rapid succession after the long-running task completes, or "misses" four invocations completely. Scheduled thread pools address this limitation by letting you provide multiple threads for executing deferred and periodic tasks.

计时器的另一个问题如果 TimerTask 抛出未经检查的异常,则表现不佳。 Timer 线程没有捕获异常,因此从 TimerTask 抛出的未经检查的异常将终止计时器线程。 计时器在这种情况下也不会恢复线程;相反,它错误地假设整个计时器被取消了。在这种情况下,已经安排但尚未执行的 TimerTask 永远不会运行,并且无法安排新任务。

Another problem with Timer is that it behaves poorly if a TimerTask throws an unchecked exception. The Timer thread doesn't catch the exception, so an unchecked exception thrown from a TimerTask terminates the timer thread. Timer also doesn't resurrect the thread in this situation; instead, it erroneously assumes the entire Timer was cancelled. In this case, TimerTasks that are already scheduled but not yet executed are never run, and new tasks cannot be scheduled.

来自 Java Concurrency in Practice ,第6.2.5节。

From Java Concurrency in Practice, section 6.2.5.

未来 s 可以限制在指定时间内运行(抛出 TimeoutException 如果无法及时完成。)

And Futures can be constrained to run at most for the specified time (throwing a TimeoutException if it could not finish in time).

如果您不喜欢上述内容,可以让任务测量自己的执行时间,如下所示:

If you don't like the above, you can make the task measure its own execution time, as below:

int totalTime = 50000; // in nanoseconds
long startTime = System.getNanoTime();
boolean toFinish = false;

while (!toFinish) 
{
    System.out.println("Task!");
    ...
    toFinish = (System.getNanoTime() - startTime >= totalTime);
}

这篇关于在一段时间内运行代码的更好方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆