我最近阅读了Quasar提供了"轻量级" / Go-like"用户模式" JVM的线程(它也有像Akka一样的Erlang启发的Actor系统,但这不是主要问题)
例如:
package jmodern;
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.strands.Strand;
import co.paralleluniverse.strands.channels.Channel;
import co.paralleluniverse.strands.channels.Channels;
public class Main {
public static void main(String[] args) throws Exception {
final Channel<Integer> ch = Channels.newChannel(0);
new Fiber<Void>(() -> {
for (int i = 0; i < 10; i++) {
Strand.sleep(100);
ch.send(i);
}
ch.close();
}).start();
new Fiber<Void>(() -> {
Integer x;
while((x = ch.receive()) != null)
System.out.println("--> " + x);
}).start().join(); // join waits for this fiber to finish
}
}
据我所知,上面的代码并没有产生任何JVM /内核线程,所有这些都是在用户模式线程中完成的(或者他们声称)这应该更便宜(就像Go协同例程一样)我理解正确)
我的问题是这个 - 据我所知,在Akka中,一切仍然基于JVM线程,这是大多数时间映射到本机OS内核线程(例如POSIX系统中的pthread),例如,据我所知,没有用户模式线程/像Akka中的协同例程/轻量级线程一样,我理解正确吗?
如果是这样,那么你知道它是否是一个设计选择?或者将来在Akka有一个类似轻量级线程的计划?
我的理解是,如果你有一百万个Actors但其中大多数是阻塞的,那么Akka可以用更少的物理线程来处理它,但是如果它们中的大多数都是非阻塞的,你仍然需要来自系统的一些响应(例如服务)数以百万计的流量传输的小请求然后我可以看到用户模式线程实现的好处,这可以允许更多的线程&#34;以更低的成本创建切换和终止(当然,唯一的好处是为许多客户平均分配响应能力,但响应能力仍然很重要)
我的理解或多或少是正确的吗?如果我错了,请纠正我。
<子> *我可能完全混淆了用户模式线程与go / co-routines和轻量级线程,上面的问题依赖于我对它们都是相同的不了解。
答案 0 :(得分:8)
Akka是一个非常灵活的库,它允许你安排演员使用(基本上可以通过一系列特征归结为)一个简单的特征ExecutionContext
,如你所见,接受{{1 s并以某种方式执行它们。因此,据我所知,很可能可以写出类似于Quasar的绑定并将其用作&#34;后端&#34;对于Akka演员。
但是,Quasar和类似的库可能会为光纤之间的通信提供特殊的实用程序。我也不知道他们将如何处理像I / O这样的阻塞任务,可能他们也会有这样的机制。由于这个原因,我不确定Akka是否能够在绿色线程上正确运行。 Quasar似乎也依赖于字节码检测,这是一种相当先进的技术,可以产生很多影响,阻止它支持Akka。
但是,在使用Akka actor时,你不应该担心线程的轻量级。事实上,Akka完全能够在单一系统上创建数百万个演员(参见here),所有这些演员都可以正常工作。
这是通过对特殊类型的线程池进行巧妙的调度来实现的,例如fork-join线程池。这意味着除非actor在一些长时间运行的计算中被阻塞,否则它们可以在很多线程上运行,远远少于这些actor的数量。例如,您可以创建一个最多使用8个线程的线程池(每个核心为8核处理器一个),并且将在这些线程上安排所有actor活动。
Akka灵活性允许您配置用于特定参与者的精确调度程序(如果需要)。您可以为处于长期运行任务中的actor创建专用调度程序,例如数据库访问。有关详细信息,请参阅here。
所以,简而言之,不,你不需要演员的用户空间线程,因为演员不会一对一地映射到本机线程(除非你强制他们但是,这应该不惜一切代价避免。)
答案 1 :(得分:3)
Akka演员基本上是异步,这就是为什么你可以拥有很多它们,而Quasar演员(是的,Quasar也提供演员实现),非常接近Erlang& #39; s,同步或阻止但是它们使用光纤而不是Java(即当前操作系统)线程,所以你仍然可以使用相同的线程性能为异步,但编程风格与使用常规线程和阻塞调用一样简单。
I / O通过集成处理:Quasar includes a framework to convert both async and sync APIs into fiber-blocking和Comsat包含许多此类集成已经完成(其中一个与Java NIO直接包含在Quasar中)。
My reply to another question包含更多信息。