Java &引用;NullPointerException“;当许多引用访问我的方法时
我有这门课:Java &引用;NullPointerException“;当许多引用访问我的方法时,java,Java,我有这门课: public class A { List l; public String method() { l = new ArrayList(); try { ..... l.add(new Integer(5)); ..... } catch (Exception e) { ......
public class A {
List l;
public String method() {
l = new ArrayList();
try {
.....
l.add(new Integer(5));
.....
}
catch (Exception e) {
......
}
finally {
if(l!=null)
l=null;
}
我有许多用户运行相同的模板(gtmpl),其中包含:
A a = new A();
a.method();
问题在于用户达到
l.add(新整数(5))代码>直接在另一个执行后执行l=null代码>。我得到一个NullPointerException
。我不明白为什么?我以为每个线程都会被分配一个列表?怎么了 是否为每个线程创建a
的新实例?如果线程共享A
的实例,则类型为List
的字段/实例变量将使代码不具有线程安全性
<> P>了解线程安全(IMO)的最佳方法之一是考虑J2EE环境中提供的示例servlet。一个应用程序只创建一个servlet实例,同一个servlet实例处理多个请求(每个请求都链接到一个线程),因此,如果将实例变量放入servlet中,必然会出现线程安全问题
阅读。1)如果每个线程创建一个类a的新实例,那么,是的,您将有不同的列表
2) 如果每个线程使用相同的一个实例,但每个线程都调用方法
,那么每次都将使用l=new ArrayList()重新初始化l
代码>
如果你正在做(2)并且不希望出现这种行为,那么你可以编写最终列表l
,在构造函数中创建它,或编写最终列表l=new ArrayList()
。这样做意味着,如果您试图重新创建l
,您将得到编译错误,这将有助于提高程序的稳定性;i、 e.将来维护您的代码的人不会落入相同的陷阱。否。线程将共享相同的列表,l。不同的实例将有不同的列表。您确定NPE来自该特定行,而不是add
方法中吗?@tbsalling您能解释一下吗?我不同意。如果新对象作为局部变量在线程中创建,则将为每个线程创建一次。@Joe在这种情况下,它将是线程安全的,但如果线程共享实例,则该字段将产生问题。问题明确指出,每个线程创建一个新的局部变量a
并实例化a()
。我是否误读了这个问题;和a.方法();在模板中完成。许多线程同时执行此模板。因此,每个线程创建一个实例并访问该方法。我认为正常的行为是每个线程创建列表l。但是NullPointerException显示列表是共享的。这是我不理解的。如果您确实在每个线程中分别创建了的实例,那么该列表不会在线程之间共享。注意:您知道每次调用方法时都会调用finally块,不是吗?它和C++中的(catch)不一样。我想我们需要看更多的代码。是的,我知道finally和catch块之间的区别。我只想提到,我所说的线程是指许多用户同时运行模板(gtmpl)a=新a();和a.方法();在模板中完成。许多用户同时运行此模板。因此,每个用户创建一个实例并访问该方法。我认为正常的行为是每个线程创建列表l。但是NullPointerException显示列表是共享的。这就是我不明白的