This 引用逃逸

在Java 并发编程书里有个例子程序清单3-7 谈到 this escape。 开始没有想明白, 仔细琢磨了些时间发现代码主要的问题是在建构函数中创建了一个匿名类,然后发布了这个匿名类。 

 

import java.util.*;

public class ThisEscape {
  private final int num;

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

  private void doSomething(Event e) {
    if (num != 42) {
      System.out.println("Race condition detected");
    }
  }
}

 

这段代码如果被 编译,然后JD-GUI  反编译看到得 doSomething(e); 就会变成   

      ThisEscape.this.doSomething(e);   这个应该是 java  inner class 调用外部class的标准方式 -  外部类名.this.方法名 

 

如果进一步的深究, 我们知道  ThisEscape编译后会有两个class 文件。一个是  ThisEscape.class, 另个一个会是  ThisEscape$1.class 给这个匿名类。

 

它们的内容差不多是这个样子的 

 

 

public class ThisEscape {
  private final int num;

  public ThisEscape(EventSource source) {
    source.registerListener(new ThisEscape$1(this));
    num = 42;
  }

  private void doSomething(Event e) {
    if (num != 42)
      System.out.println(
          "Race condition detected ");
  }

  static void access$000(ThisEscape _this, Event event) {
    _this.doSomething(event);
  }
}
 

 

class ThisEscape$1 implements EventListener {
  final ThisEscape this$0;

  ThisEscape$1(ThisEscape thisescape) {
    this$0 = thisescape;
    super();
  }

  public void onEvent(Event e) {
    ThisEscape.access$000(this$0, e);
  }
}

 

这样如果 new ThisEscape$1(this) 在另外的线程中被执行的话, 就可能导致 逃逸出去的this 的 num  还没有 执行 num = 42;   Race condition detected 会不时的显示在console 里面。

 

结论  1, 就是不要在 建构函数随便创建匿名类然后 发布它们。

        2,  不用再建构函数中随便起线程, 如果起要看有没有发布匿名类对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值