Akka的轻量级线程

Era*_*dan 9 java multithreading scala akka quasar

我最近读到了Quasar,它为JVM提供了"轻量级"/类似Go的"用户模式"线程(它还有一个像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
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,上面的代码没有产生任何JVM /内核线程,所有这些都是在用户模式线程中完成的(或者他们声称)这应该更便宜(就像我正确理解的Go一样)

我的问题是 - 据我所知,在Akka中,一切都仍然基于JVM线程,这是大多数时间映射到本机OS内核线程(例如POSIX系统中的pthread),例如,根据我的理解,有没有用户模式的线程/像Akka中的协同例程/轻量级线程一样,我理解正确吗?

如果是这样,那么你知道它是否是一个设计选择?或者将来在Akka有一个类似轻量级线程的计划?

我的理解是,如果你有一百万Actors但其中大多数都是阻塞的,那么Akka可以用更少的物理线程来处理它,但是如果它们中的大多数都是非阻塞的,你仍然需要来自系统的一些响应(例如,服务百万的小请求流式传输一些数据)然后我可以看到用户模式线程实现的好处,它可以让更多的"线程"存活,创建切换和终止的成本更低(当然,唯一的好处是均匀划分响应性很多客户,但响应能力仍然很重要)

我的理解或多或少是正确的吗?如果我错了,请纠正我.

*我可能完全混淆了用户模式线程与go/co-routines和轻量级线程,上面的问题依赖于我对它们都是相同的不了解.

Vla*_*eev 9

Akka是一个非常灵活的库,它允许你安排演员使用(基本上可以归结为通过一系列特征)一个简单的特征ExecutionContext,正如你所看到的,它接受Runnables并以某种方式执行它们.因此,据我所知,可能有可能写出像Quasar这样的东西,并将其用作Akka演员的"后端".

但是,Quasar和类似的库可能会为光纤之间的通信提供特殊的实用程序.我也不知道他们将如何处理像I/O这样的阻塞任务,可能他们也会有这样的机制.因此,我不确定Akka是否能够在绿色线程上正确运行.Quasar似乎也依赖于字节码检测,这是一种相当先进的技术,可以产生很多影响,阻止它支持Akka.

但是,在使用Akka actor时,您不应该担心线程的轻量级.事实上,Akka完全能够在单一系统上创建数百万个演员(见这里),所有这些演员都可以正常工作.

这是通过对特殊类型的线程池(如fork-join线程池)进行巧妙调度来实现的.这意味着除非actor在一些长时间运行的计算中被阻塞,否则它们可以在很多线程上运行,远远少于这些actor的数量.例如,您可以创建一个最多使用8个线程的线程池(每个核心为8核处理器一个),并且将在这些线程上安排所有actor活动.

如果需要,Akka灵活性允许您配置用于特定参与者的精确调度程序.您可以为处于长期运行任务中的actor创建专用调度程序,例如数据库访问.有关更多信息,请参见此处

所以,简而言之,不,你不需要演员的用户态线程,因为演员不会一对一映射到本机线程(除非你强制它们,但是,这应该不惜一切代价避免) .