JVM:是否可以操纵框架堆栈? [英] JVM: is it possible to manipulate frame stack?

查看:93
本文介绍了JVM:是否可以操纵框架堆栈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我需要在同一线程中执行 N 个任务.这些任务有时可能需要外部存储中的某些值.我事先不知道哪个任务可能需要这样的值以及何时执行.一次性获取 M 值比在外部存储中的 M 查询中相同的 M 值要快得多.

请注意,我不能期望任务本身进行合作,可以将它们视为java.lang.Runnable对象.

现在,如我所见,理想的过程应该是

  1. 循环执行所有任务.如果一项任务要求一个外部值,请记住这一点,暂停该任务并切换到下一个任务.
  2. 一次获取所有在上一步中请求的值.
  3. 删除所有已完成的任务(暂停的任务不算作已完成).
  4. 如果还有任务,请转到步骤1,但是从暂停状态开始继续而不是执行任务.

据我所知,挂起"和恢复"某些东西的唯一方法是从JVM堆栈中删除其相关框架,将它们存储在某个地方,然后将它们推回到堆栈中,然后让JVM继续. /p>

是否有任何标准的方法(不涉及比JVM字节码更低级别的黑客入侵)?

或者您是否可以建议另一种可能的方法(除了启动 N 个线程或使任务以某种方式进行协作之外)?

解决方案

可以使用 quasar 通过代理进行堆栈切片.从任务上进行某种程度的协作是有帮助的,但是可以使用AOP从外部插入悬挂点.

(IMO最好明确说明正在发生的事情(例如使用FutureForkJoinPool).如果某些普通代码在一个线程上运行了一段时间,然后神奇地"挂起并跳转到另一个线程,使用现代语言和库,显式描述异步边界的开销应该不会太大,如果您使用通用类型编写任务,那么传递类似这样的内容就相当容易了. scalaz Future.但这不能满足您的要求.

Suppose I need to execute N tasks in the same thread. The tasks may sometimes need some values from an external storage. I have no idea in advance which task may need such a value and when. It is much faster to fetch M values in one go rather than the same M values in M queries to the external storage.

Note that I cannot expect cooperation from tasks themselves, they can be concidered as nothing more than java.lang.Runnable objects.

Now, the ideal procedure, as I see it, would look like

  1. Execute all tasks in a loop. If a task requests an external value, remember this, suspend the task and switch to the next one.
  2. Fetch the values requested at the previous step, all at once.
  3. Remove all completed task (suspended ones don't count as completed).
  4. If there are still tasks left, go to step 1, but instead of executing a task, continue its execution from the suspended state.

As far as I see, the only way to "suspend" and "resume" something would be to remove its related frames from JVM stack, store them somewhere, and later push them back onto the stack and let JVM continue.

Is there any standard (not involving hacking at lower level than JVM bytecode) way to do this?

Or can you maybe suggest another possible way to achieve this (other than starting N threads or making tasks cooperate in some way)?

解决方案

It's possible using something like quasar that does stack-slicing via an agent. Some degree of cooperation from the tasks is helpful, but it is possible to use AOP to insert suspension points from outside.

(IMO it's better to be explicit about what's going on (using e.g. Future and ForkJoinPool). If some plain code runs on one thread for a while and is then "magically" suspended and jumps to another thread, this can be very confusing to debug or reason about. With modern languages and libraries the overhead of being explicit about the asynchronicity boundaries should not be overwhelming. If your tasks are written in terms of generic types then it's fairly easy to pass-through something like scalaz Future. But that wouldn't meet your requirements as given).

这篇关于JVM:是否可以操纵框架堆栈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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