通过决赛安全发布 [英] Safe publication through final

查看:87
本文介绍了通过决赛安全发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使经过这个,我仍然不清楚最终的使用如何导致安全发布在下面的代码中。有人可以给出一个易于理解的解释。

Even after going though this, I am still not clear about how usage of final causes safe publication in the below code. Can someone give an easy-to-understand explanation.

public class SafeListener
{
    private final EventListener listener;

    private SafeListener()
    { 
         listener = new EventListener()
         {  public void onEvent(Event e)
            {  doSomething(e); }
          };
    }

    public static SafeListener newInstance(EventSource source)
    {    
          SafeListener safe = new SafeListener(); 
          source.registerListener(safe.listener);
          return safe;
    }
}


推荐答案

已编辑添加:对 Java和JSR-133的最终<的起源的有趣观点/ code>行为

关于 final 如何在新JMM中工作的规范参考,安全发布: http:// www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight

Canonical reference for how final works in the new JMM, for safe publication: http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight

简单回顾一下,我想你的代码表示code> EventSource源对象的安全发布,该对象可能会以不同的方式将事件回调到 listener 线。保证在传递的 safe.listener 引用上运行的线程将看到完全初始化的侦听器字段。 进一步保证与调用 onEvent 或与对象状态的其他交互相关的其他同步问题。

On simple review, I think your code represents "safe" publication to the EventSource source object, which presumably will be fielding event callbacks to listener in a different thread. You are guaranteed that threads operating on the safe.listener reference passed will see a fully-initialized listener field. This does not make any further guarantees about other synchronization issues associated with calls to onEvent or other interactions with the object's state.

代码保证的是,当 SafeListener 的构造函数返回静态方法内的引用时, listener 字段在未写入状态下不会被看到(即使没有显式同步)。例如:假设线程A调用 newInstance(),从而导致分配给 listener 字段。假设线程B能够取消引用监听器字段。然后,即使没有任何其他同步,线程B也能保证看到写 listener = new EventListener()... 。如果该字段不是 final ,则您将无法获得该保证。有几种(其他)方式提供不同性能和可读性的保证(显式同步,使用原子引用,使用易失性)。

What is guaranteed by your code is that, when SafeListener's constructor returns a reference inside the static method, the listener field will not be seen in an unwritten state (even if there is no explicit synchronization). For example: Suppose a thread A calls newInstance(), resulting in an assignment to the listener field. Suppose that a thread B is able to dereference the listener field. Then, even absent any other synchronization, thread B is guaranteed to see the write listener = new EventListener().... If the field were not final, you would not receive that guarantee. There are several (other) ways of providing the guarantee (explicit synchronization, use of an atomic reference, use of volatile) of varying performance and readability.

并非所有合法的都是可取的。建议你看看 JCiP ,也许这个关于安全发布技术的文章

Not everything that's legal is advisable. Suggest you take a look at JCiP and perhaps this article on safe publication techniques.

近期,相关问题在这里:内存障碍和编码...... / a>,Java多线程和安全发布

A recent, related question is here: "Memory barriers and coding...", "Java multi-threading & Safe Publication".

这篇关于通过决赛安全发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆