java 停止 code_如何在Java中的一段时间后停止执行?

在代码中,变量计时器将指定结束while循环的持续时间,例如60秒。

while(timer) {

//run

//terminate after 60 sec

}

似乎我们在这里重新讨论一个旧线程:stackoverflow.com/questions/2550536/…

可能重复如何超时线程

long start = System.currentTimeMillis();

long end = start + 60*1000; // 60 seconds * 1000 ms/sec

while (System.currentTimeMillis() < end)

{

// run

}

但是如果循环的一次迭代在59秒开始并且循环的每次迭代花费超过1秒时开始,你会超过60秒吗?这是最好的。我要求纯粹的无知。

@Ramy:不。 start和end是绝对时间,以纪元(1970年1月1日午夜)为单位,以毫秒为单位。没有翻滚。

好的,但检查只发生在循环的开始。因此,如果在循环开始时,说已经过了59秒,并且循环的每次迭代都需要5秒。下一次while循环是条件被检查时,将经过64秒。是的,还是我错过了什么?

@Ramy:你还在想念它。循环从零毫秒开始(对于所有意图和目的)。把它想象成数学设置的方式:在我进入循环之前,我得到当前时间。为了确定循环何时结束,我将60秒(60,000 ms)添加到当前时间。循环条件在60秒内为假。

我相信拉米是对的。假设循环中的工作需要7秒才能完成。一次运行后,您将在7秒,然后是14 ......直到您完成8次迭代,总共56秒。检查将成功(因为您未满60岁),但计算将需要7秒。再次检查时,你的时间是63秒。随着时间的推移,这是5%。

对,我和你在一起。但是如果我们在循环中达到六十秒怎么办?这绝对是最好的方法,但MBCook看到了我的观点。

这个解决方案很好,我的程序没有硬性限制。感谢你们!

@MBCook:我不明白你的观点。什么是更好的解决方案?中断循环中间的计算?疑。

@downvoter:有什么意见吗?

我倾向于同意拉米。只要循环中的代码的持续时间不超过end-start,您的建议才有效。如果名为// run的位持续61秒 - >失败。

@MattBall为什么打断计算是否值得怀疑?这真的取决于你的需求。可能你有一些downvotes,因为你没有解释,你的代码真正的目的是什么 - >防止"运行" - 代码在60秒后再次执行。这与"60秒后终止"完全不同,人们 - 阅读问题 - 可能会被期望做到。

您应该尝试新的Java Executor服务。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

有了这个,你不需要自己编程循环时间。

public class Starter {

public static void main(final String[] args) {

final ExecutorService service = Executors.newSingleThreadExecutor();

try {

final Future f = service.submit(() -> {

// Do you long running calculation here

Thread.sleep(1337); // Simulate some delay

return"42";

});

System.out.println(f.get(1, TimeUnit.SECONDS));

} catch (final TimeoutException e) {

System.err.println("Calculation took to long");

} catch (final Exception e) {

throw new RuntimeException(e);

} finally {

service.shutdown();

}

}

}

这里设置的超时值是多少?

"超时"是什么意思? Thread.sleep(1337);?

我相信"超时",@ nick表示服务关闭之前的时间。

@nikk超时为"1"秒。看看:f.get()

如果你不能超过你的时间限制(这是一个硬限制),那么线程是你最好的选择。一旦达到时间阈值,就可以使用循环来终止线程。当时该线程中发生的任何事情都可能被中断,允许计算几乎立即停止。这是一个例子:

Thread t = new Thread(myRunnable); // myRunnable does your calculations

long startTime = System.currentTimeMillis();

long endTime = startTime + 60000L;

t.start(); // Kick off calculations

while (System.currentTimeMillis() < endTime) {

// Still within time theshold, wait a little longer

try {

Thread.sleep(500L);  // Sleep 1/2 second

} catch (InterruptedException e) {

// Someone woke us up during sleep, that's OK

}

}

t.interrupt();  // Tell the thread to stop

t.join();       // Wait for the thread to cleanup and finish

这将使你的解决方案大约1/2秒。通过在while循环中更频繁地轮询,可以降低它。

你的runnable的运行看起来像这样:

public void run() {

while (true) {

try {

// Long running work

calculateMassOfUniverse();

} catch (InterruptedException e) {

// We were signaled, clean things up

cleanupStuff();

break;           // Leave the loop, thread will exit

}

}

根据Dmitri的回答更新

Dmitri指出了TimerTask,它可以让你避免循环。你可以只进行连接调用,你设置的TimerTask将负责中断线程。这样可以让您获得更精确的分辨率,而无需循环轮询。

但是,这不是.interrupt()的工作方式。除非线程被阻塞,否则它只是设置interrupted标志,线程仍然必须检查它以停止执行。此外,InterruptedException是一个经过检查的异常,你不能只是把它扔到一些任意代码(你的例子不会编译)。

取决于while循环正在做什么。如果有可能长时间阻塞,请使用TimerTask计划任务设置stopExecution标志,并.interrupt()设置线程。

只有循环中的时间条件,它可以永远坐在那里等待输入或锁定(然后再次,可能不是你的问题)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 可以通过动态编译和加载类的方式来实现将字符串作为 Java 代码执行的功能。下面是一个简单的示例,假设我们有一个字符串表示了一个 Java 类的代码: ```java String code = "public class MyTest {\n" + " public static void main(String[] args) {\n" + " System.out.println(\"Hello World!\");\n" + " }\n" + "}"; ``` 我们可以通过以下步骤将这段字符串作为 Java 代码执行: 1. 使用 Java Compiler API 将字符串编译为字节码: ```java JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); JavaFileObject file = new JavaSourceFromString("MyTest", code); Iterable<? extends JavaFileObject> compilationUnits = Arrays.asList(file); CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnits); boolean success = task.call(); ``` 2. 如果编译成功,使用自定义的 ClassLoader 加载生成的字节码: ```java if (success) { ClassLoader classLoader = new MyClassLoader(); Class<?> cls = classLoader.loadClass("MyTest"); Method method = cls.getDeclaredMethod("main", String[].class); method.invoke(null, new Object[] { null }); } ``` 其,`MyClassLoader` 是一个自定义的 ClassLoader,用于从字节数组加载类: ```java class MyClassLoader extends ClassLoader { @Override public Class<?> findClass(String name) throws ClassNotFoundException { byte[] bytes = getBytesForClass(name); return defineClass(name, bytes, 0, bytes.length); } private byte[] getBytesForClass(String name) { // TODO: 从文件或其他地方获取字节码 } } ``` 上述示例仅供参考,实际使用需要注意安全性和异常处理等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值