用Java实现协程

这个问题与我有关Java中现有协程实现的问题有关。如我所怀疑的,如果事实证明Java中尚没有完整的协程实现,那么实现这些协程将需要什么?

正如我在该问题中所说的,我了解以下内容:

  1. 您可以将“协程”实现为后台的线程/线程池。
  2. 您可以在后台使用JVM字节码来完成棘手的事情,以使协程成为可能。
  3. 所谓的“达芬奇机” JVM实现具有使协程在无需字节码操作的情况下就可以实现的原语。
  4. 也有多种基于JNI的协程方法。

我将依次解决每个人的不足之处。

回答:

这种“解决方案”是病态的。协程的整个目的是 避免

线程,锁定,内核调度等开销。协程应该轻巧,快速,并且只能在用户空间中执行。根据具有严格限制的全倾斜线程来实现它们会失去所有优势。

回答:

该解决方案更实用,尽管很难实现。这大致相当于跳入C语言中的协程库的汇编语言(这是其中的多少个),其优点是您只需要担心一种架构就可以了。

除非您可以找到在不兼容的堆栈上执行相同操作的方法,否则,这将使您只能在完全兼容的JVM堆栈上运行代码(例如,这意味着没有Android)。但是,如果确实找到了解决方法,那么您现在已经将系统复杂性和测试需求提高了一倍。

回答:

达芬奇机很适合实验,但是由于它不是标准的JVM,因此它的功能不会在任何地方都可用。实际上,我怀疑大多数生产环境都将特别禁止使用达芬奇机器。因此,我可以用它来进行出色的实验,但不能用于我希望发布到现实世界中的任何代码。

这也具有类似于上面的JVM字节码操作解决方案的附加问题:在替代堆栈(如Android的堆栈)上将不起作用。

回答:

这种解决方案完全没有用Java来做到这一点。CPU和操作系统的每种组合都需要独立的测试,并且每一个都是潜在的令人沮丧的细微故障点。另外,当然,我可以将自己完全束缚在一个平台上,但这也使得在Java中做事情完全没有意义。

所以…

不使用这四种技术之一,是否可以用Java实现协程?还是我会被迫使用气味最小的那四种(JVM操作)中的一种?


编辑添加:

只是为了确保避免混淆,这是 与_我的另一个 _相关的 问题,但并非相同。为了避免不必要地重新发明轮子,那个人正在寻找

实现。这个问题是一个问题,如果另一个问题无法解决,如何在Java中实现协程。目的是在不同的线程上保留不同的问题。

回答:

我来看一下:http :

//www.chiark.greenend.org.uk/~sgtatham/coroutines.html,它非常有趣,应该提供一个不错的起点。但是我们当然使用Java,所以我们可以做得更好(或者可能更糟,因为没有宏:))

根据我对协程的了解,您通常会有一个 和一个

协程(或者至少这是最常见的模式)。但是从语义上讲,您不希望生产者致电消费者,反之亦然,因为这会引入不对称性。但是考虑到基于堆栈的语言的工作方式,我们将需要有人来进行调用。

因此,这是一个非常简单的类型层次结构:

public interface CoroutineProducer<T>

{

public T Produce();

public boolean isDone();

}

public interface CoroutineConsumer<T>

{

public void Consume(T t);

}

public class CoroutineManager

{

public static Execute<T>(CoroutineProducer<T> prod, CoroutineConsumer<T> con)

{

while(!prod.IsDone()) // really simple

{

T d = prod.Produce();

con.Consume(d);

}

}

}

当然,现在最困难的部分是 实现 接口,特别是很难将计算分为几个步骤。为此,您可能需要其他整套

。基本思想是我们要模拟控件的非本地传递(最后,它有点像在模拟goto)。我们基本上希望pc通过将当前操作的状态保留在堆中而不是堆栈中来摆脱使用堆栈和(程序计数器)的麻烦。因此,我们将需要一堆帮助程序类。

例如:

假设在一个理想的世界中,您想要编写一个看起来像这样的使用者(伪代码):

boolean is_done;

int other_state;

while(!is_done)

{

//read input

//parse input

//yield input to coroutine

//update is_done and other_state;

}

我们需要抽象局部变量like

is_doneother_state,并且需要抽象while循环本身,因为我们的yieldlike操作不会使用堆栈。因此,让我们创建一个while循环抽象和相关类:

enum WhileState {BREAK, CONTINUE, YIELD}

abstract class WhileLoop<T>

{

private boolean is_done;

public boolean isDone() { return is_done;}

private T rval;

public T getReturnValue() {return rval;}

protected void setReturnValue(T val)

{

rval = val;

}

public T loop()

{

while(true)

{

WhileState state = execute();

if(state == WhileState.YIELD)

return getReturnValue();

else if(state == WhileState.BREAK)

{

is_done = true;

return null;

}

}

}

protected abstract WhileState execute();

}

这里的基本技巧是将 变量移动为 变量,并将作用域块转换为类,这使我们能够在产生返回值之后“重新输入”“循环”。

现在实施我们的生产者

public class SampleProducer : CoroutineProducer<Object>

{

private WhileLoop<Object> loop;//our control structures become state!!

public SampleProducer()

{

loop = new WhileLoop()

{

private int other_state;//our local variables become state of the control structure

protected WhileState execute()

{

//this implements a single iteration of the loop

if(is_done) return WhileState.BREAK;

//read input

//parse input

Object calcluated_value = ...;

//update is_done, figure out if we want to continue

setReturnValue(calculated_value);

return WhileState.YIELD;

}

};

}

public Object Produce()

{

Object val = loop.loop();

return val;

}

public boolean isDone()

{

//we are done when the loop has exited

return loop.isDone();

}

}

对于其他基本控制流结构,可以采取类似的技巧。理想情况下,您将建立一个包含这些帮助程序类的库,然后使用它们来实现这些简单的接口,这些接口最终将为您提供协同例程的语义。我确信我在这里编写的所有内容都可以得到概括和扩展。

以上是 用Java实现协程 的全部内容, 来源链接: utcz.com/qa/432392.html

回到顶部