首先我要说的是,我有很多Java经验,但最近才对函数式语言感兴趣.最近我开始关注Scala,这似乎是一种非常好的语言.
但是,我一直在阅读Scala 编程中的 Scala的Actor框架,有一点我不明白.在第30.4章中,它表示使用react而不是receive可以重用线程,这对性能有好处,因为线程在JVM中很昂贵.
这是否意味着,只要我记得打电话react而不是receive,我可以开始尽可能多的演员?在发现Scala之前,我一直在和Erlang一起玩,编程Erlang的作者自豪地生成了超过20万个进程,而且不会出汗.我讨厌用Java线程做到这一点.与Erlang(和Java)相比,我在Scala中看到了什么样的限制?
此外,此线程如何在Scala中重用?为简单起见,我们假设我只有一个线程.我开始的所有演员都会在这个帖子中按顺序运行,还是会进行某种任务切换?例如,如果我启动两个互相ping消息的actor,如果它们在同一个线程中启动,我是否会冒死锁?
根据Scala编程,编写演员使用react比使用更困难receive.这听起来似乎有道理,因为react不会回来.然而,本书接着展示了如何react使用循环内部Actor.loop.结果,你得到了
loop {
react {
...
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这看起来非常相似
while (true) {
receive {
...
}
}
Run Code Online (Sandbox Code Playgroud)
在本书前面使用过.尽管如此,这本书还是说"在实践中,程序至少需要少数几个receive".那我在这里错过了什么?除了回归之外,receive做什么不能做到react?为什么我关心?
最后,进入我不理解的核心:本书不断提及如何使用react可以丢弃调用堆栈来重用线程.这是如何运作的?为什么有必要丢弃调用堆栈?当函数通过抛出异常(react)而终止时,为什么可以放弃调用堆栈,而不是当它通过返回(receive)终止时?
我的印象是Scala中的Programming一直在掩盖这里的一些关键问题,这是一种耻辱,因为否则它是一本真正优秀的书.
我已经阅读过什么设计决策有利于Scala的Actors而不是JMS的问题和答案?.
通常,我们使用已经存在多年的消息传递解决方案:将诸如WebSphere MQ或Apache ActiveMQ的JMS实现用于点对点通信,或者使用Tibco Rendevous用于多播消息传递.
它们非常稳定,经过验证,可提供高可用性和高性能.然而,配置和设置似乎比Akka复杂得多.
何时以及为什么我应该将Akka用于上述产品(WebSphere MQ或ActiveMQ)到目前为止已成功使用的一些用例?为什么我应该考虑在未来的项目中使用Akka而不是WebSphere MQ或Tibco RV?
什么时候应该避开Akka?它是否提供与其他解决方案相同的高可用性和性能?或者甚至将Akka与其他消息中间件进行比较是一个坏主意?
也许在JVM环境中还有另一个消息传递解决方案除了JMS(点对点),TibcoRV(多播)和Akka之外我还应该考虑?
我已经和我一起工作Node.js了一段时间,并认为自己对Java很好.但我刚刚发现Akka并立即对其演员模式感兴趣(据我所知).
现在,假设我的JavaScript技能与我的Scala/Java技能相当,我想专注于任一系统的实用性.特别是在Web服务方面.
据我所知,Node非常适合处理许多并发操作.我想资产管理系统的一个好的Node网络服务可以很好地处理许多用户同时提交更改(在大型,繁忙的流量应用程序中).
但是在阅读了Akka中的演员之后,它会在同样的事情上表现出色.我喜欢将工作量减少到一口大小的想法.此外,多年前我涉足Erlang并爱上了它使用的消息传递系统.
我处理许多处理复杂业务逻辑的应用程序,我认为现在是时候把它们加入到一个或另一个中.特别是升级传统的Struts和C#应用程序.
无论如何,避免神圣的战争,两个系统如何根本不同?它们似乎都面向同一个目标.也许Akka的"自我修复"架构具有优势.
编辑
看起来我正在接近投票.请不要将此问题视为"哪个更好,节点还是akka?".我正在寻找的是事件驱动库(如Node和基于演员的库,如Akka)的根本区别.
对于线程与线程相比,Actors的工作方式是否有任何好的和简短的解释?
一个线程不能被视为一个actor并将消息发送到其他线程吗?我看到了一些不同,但对我来说并不是那么清楚.我可以通过不同的线程使用任何语言的Actors吗?
使用Scala Actors而不是JMS有什么区别?
例如,从性能和可伸缩性的角度来看,与JMS相比,Scala Actor模型添加了什么?在哪些情况下使用Actors而不是JMS更有意义,即Actors解决JMS无法解决的问题是什么?
随着Scala 2.9.0的发布,Typesafe Stack也被宣布,它结合了Scala语言和Akka框架.现在,虽然Scala在其标准库中有演员,但Akka使用自己的实现.而且,如果我们寻找其他实现,我们也会发现Lift和Scalaz也有实现!
那么,这些实现之间有什么区别?
我一直在研究学习erlang,结果一直在阅读(好的,略读)演员模型.
根据我的理解,actor模型只是一组函数(在erlang中称为"processes"的轻量级线程中运行),它们只通过消息传递相互通信.
在C++或任何其他语言中实现这似乎相当简单:
class BaseActor {
std::queue<BaseMessage*> messages;
CriticalSection messagecs;
BaseMessage* Pop();
public:
void Push(BaseMessage* message)
{
auto scopedlock = messagecs.AquireScopedLock();
messagecs.push(message);
}
virtual void ActorFn() = 0;
virtual ~BaseActor() {} = 0;
}
Run Code Online (Sandbox Code Playgroud)
每个进程都是派生的BaseActor的一个实例.演员只能通过消息传递相互通信.(即推).Actors在初始化时使用中心映射注册自己,允许其他actor找到它们,并允许中心函数运行它们.
现在,我明白我错过了,或者更确切地说,在这里掩盖了一个重要的问题,即:缺乏屈服意味着单个演员可以不公平地消耗过多的时间.但是跨平台协程是否会使C++难以实现?(例如,Windows有光纤.)
还有什么我想念的,或者这个模型真的很明显吗?
我绝对不是想在这里开始一场火焰战争,我只想了解我所缺少的东西,因为这基本上就是我已经做过的能够在某种程度上推断并发代码的原因.
我目前正试图开始使用Akka,我面临一个奇怪的问题.我的演员有以下代码:
class AkkaWorkerFT extends Actor {
def receive = {
case Work(n, c) if n < 0 => throw new Exception("Negative number")
case Work(n, c) => self reply n.isProbablePrime(c);
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我开始工作的方式:
val workers = Vector.fill(nrOfWorkers)(actorOf[AkkaWorkerFT].start());
val router = Routing.loadBalancerActor(SmallestMailboxFirstIterator(workers)).start()
Run Code Online (Sandbox Code Playgroud)
这就是我关闭所有东西的方式:
futures.foreach( _.await )
router ! Broadcast(PoisonPill)
router ! PoisonPill
Run Code Online (Sandbox Code Playgroud)
现在发生的事情是,如果我发送工具消息,其中n> 0(没有抛出异常),一切正常,应用程序正常关闭.但是,只要我发送一条导致异常的消息,应用程序就不会终止,因为仍有一个actor正在运行,但我无法弄清楚它来自哪里.
如果它有帮助,这是有问题的线程的堆栈:
Thread [akka:event-driven:dispatcher:event:handler-6] (Suspended)
Unsafe.park(boolean, long) line: not available [native method]
LockSupport.park(Object) line: 158
AbstractQueuedSynchronizer$ConditionObject.await() line: 1987
LinkedBlockingQueue<E>.take() line: 399
ThreadPoolExecutor.getTask() line: 947
ThreadPoolExecutor$Worker.run() line: 907
MonitorableThread(Thread).run() line: …Run Code Online (Sandbox Code Playgroud) 我发现还有一个Akka演员模型,所以我想知道Akka的演员和Scala的演员模特之间有什么区别?