构造函数中启动线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ThisEscape {
private String name;

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

// 启动线程,此时this引用逃逸
Thread thread = new Thread() {
public void run() {
doSomething();
}
};
thread.start();
}

private void doSomething() {
System.out.println(name);
}
}

在这个例子中,构造函数创建了一个匿名内部类,并将其实例化并注册到事件源对象上。此外,构造函数还创建并启动了一个新线程,该线程也会调用doSomething方法。由于在构造函数执行期间,对象还没有完全构造完成,因此在该线程中访问name字段可能会导致不可预期的结果。

构造函数中将this传递给其他线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(new EventListener() {
public void onEvent(Event e) {
doSomething();
}
});

HelperThread helper = new HelperThread(this);
helper.start();
}

private void doSomething() {
System.out.println("do something");
}

private class HelperThread extends Thread {
private ThisEscape escape;

public HelperThread(ThisEscape escape) {
this.escape = escape;
}

public void run() {
escape.doSomething();
}
}
}

在这个例子中,构造函数创建了一个HelperThread对象,并将ThisEscape对象作为参数传递给它。HelperThread对象的run方法中访问了ThisEscape对象的doSomething方法,此时ThisEscape对象可能还没有完全构造完成,因此可能导致不可预期的结果。

构造函数中注册回调对象

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ThisEscape {
public ThisEscape() {
EventManager.getInstance().register(new EventListener() {
public void onEvent(Event e) {
doSomething();
}
});
}

private void doSomething() {
System.out.println("do something");
}
}

在这个例子中,构造函数中将匿名内部类的实例注册到了事件管理器中。由于事件管理器可能在ThisEscape对象构造完成之前就开始调用匿名内部类实例的onEvent方法,因此可能会导致不可预期的结果。

参考

《Java并发编程实战》