2013-06-18 46 views
1

我有這個類:「NullPointerException異常」時,多次提到訪問我的方法

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=null;之後,用戶直接到達l.add(new Integer(5));的情況。我得到一個NullPointerException。我不明白爲什麼?我認爲每個線程都會被分配一個列表?哪裏不對?

+0

編號線程將共享相同的列表l。 A的不同_instances_將有不同的列表。 – tbsalling

+0

你確定NPE是來自那一行嗎,不是在'add'方法裏面? – Joe

+2

@tbsalling你能解釋一下嗎?我不同意。如果新對象是作爲局部變量在線程中創建的,則它將爲每個線程創建一次。 – Joe

回答

2

您是否爲每個線程創建了A的新實例?如果線程共享A的實例,那麼類型List的字段/實例變量將使代碼不是線程安全的。

瞭解線程安全(IMO​​)的最佳方法之一是考慮J2EE環境中提供的示例Servlets。只爲應用程序創建一個servlet實例,並且同一個servlet實例處理多個請求(每個請求都鏈接到一個線程),因此如果將實例變量放在servlet中,那麼您的綁定會遇到線程安全問題。

this article一讀。

+0

A a = new A();和a.method();在模板中完成。許多用戶同時運行此模板。所以每個用戶都創建一個A的實例並訪問該方法。我認爲正常的行爲是每個線程創建List l。但NullPointerException顯示列表是共享的。這就是我不明白 –

0

1)如果每個線程創建一個新的類A實例,那麼,是的,你將有不同的列表。

2)如果每個線程使用一個相同的實例,但每個人讓到method調用,那麼您將被重新初始化每次ll = new ArrayList();

如果你正在做的(2)和不希望行爲,那麼你可以寫final List l;,在構造函數中創建它,或者寫final List l = new ArrayList()。這樣做意味着如果您嘗試重新創建l將會遇到編譯錯誤,這將有助於程序的穩定性;即將來維護您的代碼的人不會陷入同一陷阱。

+0

A =新的A();和a.method();在模板中完成。許多線程同時執行此模板。所以每個線程都創建一個A的實例並訪問該方法。我認爲正常的行爲是每個線程創建List l。但NullPointerException顯示列表是共享的。這是我不明白的。 –

+0

如果您確實在每個線程中分別創建A的實例,則線程之間不共享該列表。在需要注意的事情上:你知道每次調用方法時都會調用finally塊,否?它與C++中的(catch ...)不一樣。我認爲我們需要看到更多的代碼。 – Bathsheba

+0

是的,我知道終於和catch塊之間的區別。我只想提一提,我的意思是,許多用戶同時運行模板(gtmpl) –

相關問題