Java - 如何停止运行任意代码的线程?
在我的应用程序中,在单独的线程中运行用户提交的代码[1],在某些情况下,代码可能需要很长时间才能运行,甚至可能有无限循环!在这种情况下,我该如何停止该特定线程?
我无法控制用户代码,因此我无法从内部检查 Thread.interrupted() 。我也不能粗心地使用Thread.stop()。我也不能将这些代码放在单独的进程中。
那么,有什么办法可以处理这种情况吗?
[1] 我使用的是 JRuby,用户代码是用 ruby 编写的。
In my application which runs user submitted code[1] in separate threads, there might be some cases where the code might take very long to run or it might even have an infinite loop! In that case how do I stop that particular thread?
I'm not in control of the user code, so I cannot check for Thread.interrupted() from the inside. Nor can I use Thread.stop() carelessly. I also cannot put those code in separate processes.
So, is there anyway to handle this situation?
[1] I'm using JRuby, and the user code is in ruby.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
根据您提供的限制:
Thread.stop()
。你的问题的答案是“不,没有办法处理这种情况”。您已经非常系统地设计了一些东西,以便您对不受信任的第三方代码具有零控制。这是……次优设计。
如果您希望能够处理任何事情,则必须放松上述限制中的一项(或最好是多项!)。
编辑添加:
如果这是一个(另一个)约束,您可能有一种方法可以解决这个问题,而无需强迫您的客户更改代码。在另一个进程中启动 Ruby 代码,并使用某种形式的 IPC 机制与主代码库进行交互。为了避免强制 Ruby 代码突然必须编码为使用显式 IPC,请为您的 API 放入一组代理对象,这些对象在幕后执行 IPC,这些对象本身在您自己的服务器中调用代理对象。这样,您的客户端代码就会产生在服务器内部工作的错觉,而您将这些代码囚禁在自己的进程中(您最终可以
kill -9
作为最终制裁)。稍后您将希望让您的客户摆脱这种幻想,因为 IPC 和本机调用非常不同,将其隐藏在代理后面可能是邪恶的,但这是您在弃用 API 时可以使用的权宜之计并将您的客户转移到新的 API。
With the constraints you've provided:
Thread.interrupted()
.Thread.stop()
.The answer to your question is "no, there is no way of handling this situation". You've pretty much systematically designed things so that you have zero control over untrusted third-party code. This is ... a suboptimal design.
If you want to be able to handle anything, you're going to have to relax one (or preferably more!) of the above constraints.
Edited to add:
There might be a way around this for you without forcing your clients to change code if that is a(nother) constraint. Launch the Ruby code in another process and use some form of IPC mechanism to do interaction with your main code base. To avoid forcing the Ruby code to suddenly have to be coded to use explicit IPC, drop in a set of proxy objects for your API that do the IPC behind the scenes which themselves call proxy objects in your own server. That way your client code is given the illusion of working inside your server while you jail that code in its own process (which you can ultimately
kill -9
as the ultimate sanction should it come to that).Later you're going to want to wean your clients from the illusion since IPC and native calls are very different and hiding that behind a proxy can be evil, but it's a stopgap you can use while you deprecate APIs and move your clients over to the new APIs.
我不确定这里的 Ruby 角度(或线程角度),但是如果您正在运行用户提交的代码,您最好在单独的进程中运行它,而不是在同一进程的单独线程中运行它。
规则第一:永远不要相信用户输入。如果输入是代码则更少!
干杯
I'm not sure about the Ruby angle (or of the threading angle) of things here, but if you're running user-submitted code, you had best run it in a separate process rather than in a separate thread of the same process.
Rule number one: Never trust user input. Much less if the input is code!
Cheers
通常你有一个变量来指示停止线程。然后其他一些线程会将此变量设置为 true。最后,定期检查变量是否已设置。
但鉴于您无法更改用户代码,恐怕没有安全的方法。
Usually you have a variable to indicate to stop a thread. Some other thread then would set this variable to true. Finally you periodically check, whether the variable is set or not.
But given that you can't change user code , I am afraid there isn't a safe way of doing it.
对于正在运行的线程 Thread.Interrupt 实际上不会像 sfussenegger 提到的那样停止(感谢 sfussenegger 在阅读规范后回忆起来)。
使用共享变量来表明它应该停止正在做的事情。线程应该定期检查变量(例如:使用 while 循环)并有序退出。
For Running Thread
Thread.Interrupt
wont actually stop as sfussenegger mentioned aforth (thanks sfussenegger recollected after reading spec).using a shared variable to signal that it should stop what it is doing. The thread should check the variable periodically,(ex : use a while loop ) and exit in an orderly manner.