Java线程上的变量范围

时间:2015-10-06 20:39:41

标签: java android multithreading

考虑这个片段。

private String global_s;

public void onClick(View v) {
global_s = "String";

  new Thread(new Runnable() {
    public void run() {
        final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");     
        ImageView mImageView = (ImageView) findViewById(R.id.imageview);
        mImageView.setImageBitmap(bitmap);

        final String local_s = global_s;
        TextView tv = (TextView) findViewById(R.id.textview);
        tv.setText(local_s);
        });
    }
  }).start();
}

线程结束后位图引用是否仍然存活(垃圾收集器未收集)?因为它是在mImageView上分配的。

另外,local_s怎么样?它是否会被global_s reference替换?

2 个答案:

答案 0 :(得分:2)

bitmaplocal_s都是局部变量,因此run()结束后会立即处理(想想毫秒)。但是,Bitmap和String对象可能会作为实例字段存储在ImageView和TextView对象中,共享它们的生命周期(想想秒数)。

关于local_sglobal_s之间的链接:local_s会在分配时捕获global_s的值,但几乎无用,因为它会立即传递给{{ 1}} - 请注意,Java总是按值传递,因此会立即生成另一个副本并将其传递给.setText(),这可能会将其存储在绘制时读取的实例字段中以呈现文本。

答案 1 :(得分:1)

GC不会破坏仍然可以访问的对象;即,只要他们有参考,他们就不会被收集。如果你有5分钟,请浏览这个article,它提供了一个关于Java垃圾收集如何工作的优秀,可读的描述。

无论如何,local_s只引用global_s引用的同一对象。当线程的调用堆栈被销毁时,local_s引用变量将被销毁,但global_s仍然拥有堆上其String对象的句柄。由于mImageView存在于线程之外,因此在本地线程存在后也不会收集其引用的对象。