Java 实现无欺骗的虚拟线程

Java 实现无欺骗的虚拟线程,java,python,multithreading,gevent,Java,Python,Multithreading,Gevent,在中,有一个示例如下所示: import gevent def foo(): print('Running in foo') gevent.sleep(0) print('Explicit context switch to foo again') def bar(): print('Explicit context to bar') gevent.sleep(0) print('Implicit context switch back to

在中,有一个示例如下所示:

import gevent

def foo():
    print('Running in foo')
    gevent.sleep(0)
    print('Explicit context switch to foo again')

def bar():
    print('Explicit context to bar')
    gevent.sleep(0)
    print('Implicit context switch back to bar')

gevent.joinall([
    gevent.spawn(foo),
    gevent.spawn(bar),
])
输出是

Running in foo
Explicit context to bar
Explicit context switch to foo again
Implicit context switch back to bar
我已经测试过了,并且亲眼目睹了它的工作原理。我的一个朋友声称这完全是在一个线程中运行的。除了我想不出gevent.sleep(0)的任何实现,它不会归结为某种形式的“欺骗”(即:交换顶部的两个堆栈帧等)


有人能解释一下这是怎么回事吗?如果这是Java(或者至少是某种禁止这种堆栈操作的语言),这可能吗?(同样,不使用多线程)。

它实际上只在一个线程上运行。gevent使用greenlet,它是协同程序,而不是线程。每个给定时间只有一个堆栈(除非您使用多线程,然后在每个线程中使用greenlet)

在上面的示例中,无论何时调用sleep或joinall,当前的协同路由(greenlet)实际上都会让位给中心。把集线器想象成一个中央调度器,负责决定下一步运行哪个协同路由

为了让自己相信这一点,删除gevent.sleep(0)调用,您将看到它的行为有所不同


请注意,与线程不同,执行是确定的,因此如果您运行两次程序,它将以完全相同的顺序执行。

交换最上面的两个堆栈帧
-这是线程实际工作的方式,那么这是如何作弊的?在Java中,支持连续性的库是可能的。支持连续性的Java库可以用纯Java实现吗?如果是这样的话,那就不是作弊了。有几家使用了插装。它添加了额外的代码,这样就可以保存和恢复堆栈。我不认为它是非常快的,这就是为什么你通常更好地使用真正的线程更有效。但它是如何实现的?有什么诀窍?他们是在搞乱解释器,还是完全可以用本机python实现?它是用C编写的。它就像一个“GO-TO”,直接跳到中心。我认为C不允许从一个函数内部跳到另一个函数内部。你介意在你的答案中添加一些伪代码吗?对不起,我对确切的实现了解不够,无法添加一些伪代码