Java 在一段时间内运行代码的更好方法

Java 在一段时间内运行代码的更好方法,java,timertask,Java,Timertask,我需要在预定义的时间长度内运行一些代码,当时间结束时,它需要停止。目前,我正在使用TimerTask来允许代码执行一定的时间,但这会导致代码创建无休止的线程,而且效率很低。有更好的选择吗 现行代码 // Calculate the new lines to draw Timer timer3 = new Timer(); timer3.schedule(new TimerTask(){ public void ru

我需要在预定义的时间长度内运行一些代码,当时间结束时,它需要停止。目前,我正在使用TimerTask来允许代码执行一定的时间,但这会导致代码创建无休止的线程,而且效率很低。有更好的选择吗

现行代码

// 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);
//计算要绘制的新线
定时器定时器3=新定时器();
timer3.时间表(新TimerTask(){
公开募捐{
ArrayList Coords=新的ArrayList();
int x=Float.valueOf(lastFour[0]).intValue();
int y=Float.valueOf(lastFour[1]).intValue();
int x1=Float.valueOf(lastFour[2]).intValue();
inty1=Float.valueOf(lastFour[3]).intValue();
//可能是绕错方向了(x1,y1,x,y)?
Coords=CoordFiller.coordFillCalc(x,y,x1,y1);
字符串newCoOrds=“”;
对于(int j=0;j
[…]目前,我正在使用TimerTask来允许代码在设定的时间内执行[…]

计时器任务永远不会停止当前正在运行的任务。事实上,它的唯一目的是反复重新启动任务


如果没有与执行任务的紧密合作,就没有简单的解决方法。最好的方法是让任务监视它自己的执行,并确保它在时间结束时返回(终止)。

如果停止意味着程序必须退出,解决方案是为您的处理创建一个线程并将其标记为守护进程,启动它并在主线程睡眠中等待所需的时间,然后只需从
main()
方法返回即可


擦伤,如果停止,你的意思是停止处理。

如果你使用java5或更高版本,考虑和。使用前者,您可以安排任务在指定的延迟后或在指定的时间间隔内运行,因此它接管了
计时器的角色,更加可靠

计时器
功能管理延迟(“在100毫秒内运行此任务”)和定期(“每10毫秒运行此任务”)任务的执行。但是,
Timer
有一些缺点,应该将
ScheduledThreadPoolExecutor
视为它的替代品。[……]

计时器
只创建一个用于执行计时器任务的线程。如果计时器任务运行时间过长,则其他
计时器任务的计时精度可能会受到影响。如果一个周期性的
TimerTask
计划每10毫秒运行一次,而另一个
TimerTask
则需要40毫秒才能运行,则周期性任务在长时间运行的任务完成后会被快速连续调用四次,或者完全“错过”四次调用。定时线程池通过允许您提供多个线程来执行延迟和定期任务来解决此限制

Timer
的另一个问题是,如果
TimerTask
抛出未经检查的异常,它的行为会很差。
Timer
线程无法捕获异常,因此从
TimerTask
引发的未检查异常会终止计时器线程<代码>计时器
在这种情况下也不会恢复线程;相反,它错误地认为整个
计时器已取消。在这种情况下,已调度但尚未执行的
TimerTask
s将永远不会运行,并且无法调度新任务

摘自第6.2.5节

Future
s在指定的时间内最多执行一次(如果不能及时完成,则抛出
TimeoutException

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

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

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

还应注意,通常只需要创建一个计时器()。从代码片段中,我猜您正在创建多个Timer()对象

schedule方法中的时间是运行时间,而不是运行多长时间

考虑在for循环之前设置一个开始时间&如果超过了时间限制,则在for循环中设置一个中断

long startedAt = System.currentTimeMillis();
long finishedCorrectly = true;
for (int j = 0; j < Coords.size(); j++) {
  newCoOrds += Coords.get(j) + " ";
  if ((System.currentTimeMillis() - startedAt) > MAX_TIME_TO_RUN) {
    finishedCorrectly = false;
    break;
  }
}
long startedAt=System.currentTimeMillis();
long finishedCorrectly=true;
对于(int j=0;j最大运行时间){
finishedCorrectly=false;
打破
}
}

+1尽管有
Thread.stop()
引用,但该引用周围应该有
标记,并有一个巨大的警告,表明它在任何情况下都不是解决需要询问计时器执行情况的人的任何问题的正确方法。如果任务需要运行预定的时间长度,您需要告诉任务,并让它按照@aioobe的建议进行自我监控。谢谢,这看起来很有用。我需要的是在设定的时间段内执行代码。ScheduledThreadPoolExecutor似乎只能使用延迟和等待,不能在一段时间内执行任务,类似于Future等待执行完成。@mhollander38,我的理解是,如果调用例如
Future.get(1,TimeUnit.SECOND)
,一秒钟后,它将抛出一个
TimeoutException
,相关任务的执行将终止。不过我还没有验证它。@mhollander38,我添加了另一个解决方案,改进了(现在已删除)repost中的代码。我们已经实现了它,它正在发挥作用。非常感谢您,Péter。@Péter Török调用
Future.get(1,TimeUnit.SECOND)