[英]Variable is null when called from another thread
请向我解释该变量的奇怪行为。 从主线程创建类“ B”的实例。 在父级“ A”的构造函数中,该类称为“ B”类的抽象函数“ init”。 它初始化类“ B”的debugPaint成员。
然后,它创建一个线程,该线程定期调用函数postDraw 。 问题是,如果我分配了私有易失性Paint debugPaint = null函数postDraw, 则将debugPaint成员接收为null 。 尽管正如我在调试器中看到的那样,初始化之前已成功完成。 如果未完成对null的赋值,则一切正常。 专用volatile Paint debugPaint ; 问题是什么?
ps init和postDraw之间的时间很长,只有几秒钟。
public class A{
public A()
{
init();
}
public void draw(Canvas canvas)
{
//some code....
postDraw(canvas);
}
abstract public void postDraw(Canvas canvas);
abstract public void init();
}
public class B extends A{
private volatile Paint debugPaint=null;//=null problem! not =null ok!
@Override
public void init()
{
debugPaint=new Paint();
}
@Override
public void postDraw(Canvas canvas)
{
canvas.drawRect(0,0,128,128,debugPaint);
}
}
您的问题与线程无关。
下面的示例是一个完整的程序,演示了此问题:
当main()
例程创建一个新的B实例时,它首先调用A()构造函数。 该构造函数调用B.init(),该函数将debugPaint设置为指向新的Paint对象。 然后,在A()构造函数完成之后,将调用默认的 B()构造函数。
class Paint {
}
class Canvas {
}
abstract class A{
public A()
{
System.out.println("A.<init>() entered");
init();
System.out.println("A.<init>() exit");
}
public void draw(Canvas canvas)
{
//some code....
postDraw(canvas);
}
abstract public void postDraw(Canvas canvas);
abstract public void init();
}
class B extends A{
private volatile Paint debugPaint=null; //this assignment happens in the default B() constructor
@Override
public void init()
{
System.out.println("B.init() entered");
debugPaint=new Paint();
System.out.println("B.init() exit");
}
@Override
public void postDraw(Canvas canvas)
{
System.out.println("debugPaint=" + debugPaint);
}
}
public class Foobar {
public static void main(String[] args) {
B b = new B();
b.draw(new Canvas());
}
}
我认为这里的问题是新线程在构造函数中声明(尽管是间接地),所以当新线程启动时A不会完全实例化。
在Java中,建议不要从构造函数启动线程。 相反,应在构造后调用init()。 那应该可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.