对象发布和转义Java并发,这个引用在这里是如何转义的?

pdtvr36n  于 2023-03-16  发布在  Java
关注(0)|答案(2)|浏览(125)

最近我在学习“Java并发实践”时,遇到了发布和转义的例子,在学习了几次之后,我仍然觉得我没有完全理解这个例子。

public class ThisEscape{
       public ThisEscape(EventSource source){
            source.registerListener(
              new EventListener(){
                 public void onEvent(Event e){
                   doSomething(e);
                 }
              }
            )
       }
}

ThisEscape说明了Escape的一个重要特例--当 this 引用在构造过程中转义时。当内部EvenListener示例发布时,封闭的ThisEsape示例也会发布。但是,对象位于可预测的一致的状态。因此,从构造函数内部发布一个对象可以发布一个未完全构造的对象。即使发布是构造函数中的最后一条语句,也是如此。如果this引用在构造过程中转义,则认为对象构造不正确。
ThisEscape构造器正在使用和EventListener注册EventSource,我们在其中指定传递Event示例的onEvent行为。但在这里我假设对象构造的顺序为EventListener --> ThisEscape,那么ThisEscapethis 引用是如何传递到这里以进行转义的?

polhcujo

polhcujo1#

我认为我们应该参考这段摘录:
当内部EvenListener示例发布时,封闭的ThisEsape示例也会发布。
这让我认为doSomething()ThisEscape的方法(否则引用不会转义),这意味着ThisEscapeEventSource的侦听器,它在构造过程中通过重写EventListeneronEvent方法注册自己。
简而言之,它说:“当新事件发生时,调用doSomething()“。
在这一点上,问题是相当简单的。想象一下,我们已经在ThisEscape的构造函数中注册了一个新的侦听器......并且立即......一个事件发生了!当一个线程还在构造ThisEscape时,另一个线程已经在调用doSomething(),这可能导致非常不可预测的结果......

46qrfjad

46qrfjad2#

实际上,它需要在完成对象初始化后(构造后)注册事件,因此建议使用私有构造

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;
}

这个安全多了。

相关问题