Java 运行未来回调的参与者的线程安全

Java 运行未来回调的参与者的线程安全,java,multithreading,scala,akka,Java,Multithreading,Scala,Akka,akka文件规定: (…)您只需编写actor代码,根本不用担心并发性 在幕后,Akka将在真实线程集上运行多个参与者集,通常多个参与者共享一个线程,一个参与者的后续调用可能最终在不同的线程上处理。Akka确保此实现细节不会影响处理参与者状态的单线程性 但假设我正在构建一个未来,并通过管道将其发送到事件处理线程中的回调。例如,使用ask模式: ask(someActor, new SomeRequest(), timeout) .onSuccess(new OnSucce

akka文件规定:

(…)您只需编写actor代码,根本不用担心并发性

在幕后,Akka将在真实线程集上运行多个参与者集,通常多个参与者共享一个线程,一个参与者的后续调用可能最终在不同的线程上处理。Akka确保此实现细节不会影响处理参与者状态的单线程性

但假设我正在构建一个未来,并通过管道将其发送到事件处理线程中的回调。例如,使用ask模式:

ask(someActor, new SomeRequest(), timeout)
            .onSuccess(new OnSuccess<Object>() {
                @Override
                public void onSuccess(Object answer) throws Throwable {

                  // Modify actor state

                }
            }, getContext().system().dispatcher());
ask(someActor,newsomerequest(),超时)
.onSuccess(新的onSuccess(){
@凌驾
public void onSuccess(对象应答)抛出可丢弃{
//修改参与者状态
}
},getContext().system().dispatcher());
这是否意味着回调永远不会与事件处理线程并发执行?因此,可以安全地修改参与者状态,而不必担心同步问题?

当你说“//modify actor state”对self做了一个大动作(!)时,它应该是正常的,但如果它真的修改了参与者状态,那么它就是不正常的

Actor的threadsafe属性是因为它的邮箱和Actor属性一次只处理一封邮件。如果您不使用参与者的邮箱来修改其状态,那么您需要自己锁定/同步这些可变状态。(有关更好的解释,请参阅此链接:)

这是否意味着回调永远不会与并发执行 事件处理线程

在您的情况下,可以同时执行回调

解释:演员的线程安全性来自于。i、 Akka保证,当actor收到消息时,您的actor主体一次只能由一个线程执行

同时,如果你产生了一个线程并试图改变一些内部状态(比如变量或其他),那么akka就无法控制它。线程的消息消耗和将来的正文执行都可以并行进行

因此,可以安全地修改参与者状态,而无需担心 同步

如果您的未来块处理的是body从未使用过的变量,那么您可能不需要同步。如果有,那你就需要它