简体   繁体   English

停止可能永远循环的线程

[英]Stopping a thread that could be looping forever

I have a program where I compile java code a user types into a text field, and then run it. 我有一个程序,我将用户键入的java代码编译成文本字段,然后运行它。 A run the code in a seperate thread, so that the GUI they use to input the source code doesn't get locked up. 在单独的线程中运行代码,以便用于输入源代码的GUI不会被锁定。

The GUI has an abort button that should stop the thread. GUI有一个应该停止线程的中止按钮。 My issue is that I need to stop the compiling thread no matter what is going on inside of it, which means I must account for a case where the thread is caught in an infinite loop (due to user error), and it cannot properly end itself using a safe flag. 我的问题是我需要停止编译线程,无论它内部发生了什么,这意味着我必须考虑线程被无限循环捕获的情况(由于用户错误),并且它无法正常结束本身使用安全标志。 I've read up on many solutions that involve using a flag of some kind, but they aren't available to me because of this looping issue. 我已经阅读了许多涉及使用某种标志的解决方案,但由于这种循环问题,我无法使用它们。 I need to have the thread stop and the memory it's using freed (I can't just let it sit in the background forever, unless that is the only solution left). 我需要让线程停止并释放它正在使用的内存(我不能让它永远停留在后台,除非这是剩下的唯一解决方案)。 Any advice or alternative solutions? 任何建议或替代解决方案? Hopefully some fresh perspectives could help squash this issue. 希望一些新的观点可以帮助压制这个问题。

Edit: 编辑:

Here's a sample bit of user submitted code: 以下是用户提交代码的示例:

public class RunMe extends SomethingThatRuns {
    public void run() {
        int i = 0;
        while (i = 0) {
            //Prepare to get stuck!
        }
    }
}

I'll compile this class, and then run it. 我将编译这个类,然后运行它。 This is where it will get stuck, and the run() method can never finish, or even loop to check a flag. 这是它会卡住的地方, run()方法永远不会完成,甚至循环检查标志。

You can run it in a new JVM so you can kill it when you want. 您可以在新的JVM中运行它,以便在需要时将其终止。 Thinking about security this may be a good thing to do too. 考虑安全性这也是一件好事。

Call stop() on the thread. 在线程上调用stop()

Yes, this is a deprecated method. 是的,这是一种弃用的方法。 However, it really shouldn't be "deprecated", it should be "dangerous." 但是,它确实不应该被“弃用”,它应该是“危险的”。 In some circumstances, however, there's really no choice but to use it, and the invocation of an "agent" provided by a user is one of those cases. 但是,在某些情况下,除了使用它之外别无选择,并且用户提供的“代理”的调用就是这种情况之一。

Make sure that your program doesn't use any data that are manipulated by this user thread; 确保您的程序不使用此用户线程操纵的任何数据; or, if you do, devise some transactional mechanism to exchange data safely between the threads. 或者,如果你这样做,设计一些事务机制来在线程之间安全地交换数据。

Even this method isn't guaranteed to terminate the thread. 即使这种方法也不能保证终止线程。 For example, the user can catch the resulting Throwable and ignore it. 例如,用户可以捕获生成的Throwable并忽略它。 Or, the thread implementation might not respond to stop() calls if the thread is in some native code. 或者,如果线程在某些本机代码中,则线程实现可能不响应stop()调用。 But it's your best chance. 但这是你最好的机会。

The core issue here is the fact that the code even allows an infinite loop to be entered as part of user error. 这里的核心问题是代码甚至允许输入无限循环作为用户错误的一部分。 Fix that, and everything else will become easier to deal with. 解决这个问题,其他一切都会变得更容易处理。

Properly-behaving threads should usually terminate themselves gracefully when there's no work to do (or return quietly to a thread pool to ask for more work, if that's your application's design). 正常行为的线程通常应该在没有工作要做的时候优雅地终止(或者静静地返回到线程池以请求更多的工作,如果这是你的应用程序的设计)。 If you feel like you need to have one thread forcefully kill another then you've likely got a fundamental design issue. 如果你觉得你需要让一个线程强行杀死另一个线程,那么你可能会遇到一个基本的设计问题。 It's fine to have one thread tell another, "Hey, you should terminate now so that I can join with you..." because that allows your threads to clean things up as they finish. 让一个线程告诉另一个线程是好的, “嘿,你现在应该终止,以便我可以和你一起......”因为这可以让你的线程在完成时清理它们。 Forcefully destroying threads just isn't the right way to manage these situations. 强行销毁线程并不是管理这些情况的正确方法。

You can use them to insert a interrputed check in every loop and maybe in other places too. 您可以使用它们在每个循环中插入一个间隔检查,也可以在其他地方插入。

I can see two options: 我可以看到两个选项:

  • As you compile the user code you can edit it before. 在编译用户代码时,您可以先编辑它。 You may use ANTLR to parse and modify the code. 您可以使用ANTLR来解析和修改代码。
  • There are bytecode manipulation frameworks like ASM that allow you to manipulate code that is already compiled. 有一些字节码操作框架,如ASM,允许您操作已编译的代码。

I don't think it is easy but it might be a way. 我认为这不容易,但它可能是一种方式。

interupt(); the Thread in the gui gui中的线程

and in the code that the thread runs regularly check for Thread.interrupted() and throw an exception when you do especially inside loops 并且在线程运行的代码中检查Thread.interrupted()并在特别是内部循环时抛出异常

At a high level, you are asking how one thread might go about stopping another thread. 在较高的层次上,你问的是一个线程如何停止另一个线程。 To that end, see this SO question Stopping a Thread in Java? 为此,请参阅此问题在Java中停止线程? .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM