Zyl*_*Zyl 5 java multithreading
假设这段代码:
public class Foo {
public static Thread thread;
public String thing = "Thing!!";
public static void main(String[] args) {
new Foo().makeThread();
// <- Foo object may get garbage collected here.
thread.start();
}
private void makeThread() {
thread = new Thread(new Runnable() {
@Override
public void run() {
// !! What if the instance of Foo is long gone?
System.out.println(thing);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
这里,一个临时对象new Foo()创建一个静态保持Thread thread,它利用String thing匿名实现中的实例绑定Runnable.String thing收到的垃圾是否会在到期后收集new Foo(),还是会在其中使用run()?为什么?
Jon*_*eet 10
匿名内部类将引用它Foo,因为它是如何访问的thing.就好像你有:
public class FooRunnable implements Runnable {
private final Foo foo;
public FooRunnable(Foo foo) {
this.foo = foo;
}
public void run() {
System.out.println(foo.thing);
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
private void makeThread() {
thread = new Thread(new FooRunnable(this));
}
Run Code Online (Sandbox Code Playgroud)
所以基本上,当新线程使实现的实例保持Runnable活动时,这反过来会阻止实例Foo被垃圾回收.
das*_*ght 10
字符串thread在设置为null或其他字符串之前不会被垃圾收集Thread,因为有一个引用链从静态变量导向该对象.
引用链看起来像这样:
static thread隐式引用Foo通过派生自的匿名类实例创建它的实例Runnable.反过来,实例Foo持有一个引用thing,确保对象不会被垃圾收集.
如果Foo的例子早已不复存在怎么办?
Foo不会去任何地方,因为它通过来自Thread对象的隐式引用保持活跃.
注意:此答案故意忽略了String从字符串文字创建的实习对象的影响.
| 归档时间: |
|
| 查看次数: |
288 次 |
| 最近记录: |