逃逸分析英文作Escape Analysis。在计算机语言编译器优化原理中,逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。
当变量(或者对象)在方法中分配后,其指针有可能被返回或者被全局引用,这样就会被其他过程或者线程所引用,这种现象称作指针(或者引用)的逃逸(Escape)。
在Java 并发编程书里有个例子程序清单3-7 谈到 this escape。 开始没有想明白, 仔细琢磨了些时间发现代码主要的问题是在建构函数中创建了一个匿名类,然后发布了这个匿名类。
Java代码
- 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 给这个匿名类。
它们的内容差不多是这个样子的
Java代码
- public class ThisEscape {
- private final int num;
- public ThisEscape(EventSource source) {
- source.registerListener(new <strong><span style="color: #ff0000;">ThisEscape$1</span></strong>(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);
- }
- }
Java代码
- class ThisEscape$1 implements EventListener {
- final ThisEscape this$0;
- ThisEscape$1(<span style="color: #ff0000;">ThisEscape thisescape</span>) {
- 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 里面。
时间: 2024-10-07 09:42:19