我会看看这个: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;
}
我们需要像 和 一样抽象局部变量,我们需要抽象 while 循环本身,因为我们的 like 操作不会使用堆栈。因此,让我们创建一个 while 循环抽象和关联的类:is_done
other_state
yield
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();
}
}
对于其他基本的控制流结构,也可以做类似的技巧。理想情况下,您将构建这些帮助程序类的库,然后使用它们来实现这些简单的接口,这些接口最终将为您提供协同例程的语义。我相信我在这里写的所有内容都可以概括和扩展。