2015-06-19 20 views
0

我看到了這個NullPointerException on synchronized statement在null對象上使用syncrhonized時獲取NullPointerException

代碼

synchronized(a){ 
    a = new A() 
} 

所以根據上述答案我已經理解的是,不可能使用synchronized關鍵字上空引用

所以我改變了我的代碼如下:

synchronized(a = new A()){} 

,但我不知道這是我原來的代碼是否一致?

更新:

我想要實現的是鎖定的aa = new A())創建

+3

什麼是你想在這裏實現? – Arvind

+3

我會說這是一個糟糕的主意,因爲每次你點擊'synchronized'塊時,你都會創建另一個'A'的實例,所以沒有任何東西被阻塞。 「鎖定」對象需要在線程之間共享。可以使用'static final Object'作爲通用監視器鎖,這將是一個好主意 – MadProgrammer

+1

沒有_null object_。 – Seelenvirtuose

回答

0

synchronized(a = new A()){}

所以它的作用是將創建類A的一個新對象,並使用 作爲鎖,所以在簡單的一句話每一個線程可以同步 塊進入任何時候,因爲每個線程都有新的鎖會有 正在使用該對象的鎖,以便每個線程可以 輸入您的synchronized塊隨時隨地結果將是沒有 同步

沒有其他線程

對於實施例

class TestClass { 
    SomeClass someVariable; 

    public void myMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 

    public void myOtherMethod() { 
     synchronized (someVariable) { 
      ... 
     } 
    } 
} 

這裏我們可以然後說這兩個塊將通過2個不同的線程執行 隨時被保護而someVariable不被修改。 基本上說,這兩個塊與 變量some​​Variable同步。 但在你的情況始終存在一些新的對象,因此不會有同步

1

同步需要一個對象,將提供鎖定機制。它可以是任何對象(實際上,不帶參數同步將在這個同步),但Java API提供專用於此功能的類,例如ReentrantLock

在代碼中,您提供的每個對包含synchronized塊的函數的調用都將使用不同的對象進行鎖定,從而有效地使同步無用。

編輯: 由於您使用實際嘗試完成的內容更新了文章,因此我可以爲您提供更多幫助。

public class Creator { 
    private A a; 

    public void createA() { 
     synchronized(this) { 
      a = new A(); 
     } 
    } 
} 

我不知道這是否適合您的設計,因爲您提供的代碼示例非常小,但您應該明白。這裏使用Creator類的實例來同步A的創建。如果您在多個線程之間共享它,每個線程都會調用createA(),您可以確定一個實例化過程將在另一個實例化過程開始之前完成。

0

這兩個代碼片段不相同!

在第一個代碼片段中,您在a引用的某個對象上同步,然後更改不會更改同步對象的引用。

在第二個片段中,您首先分配一個新創建的對象來引用a,然後對其進行同步。所以同步對象將是新的。

通常,更改同步語句中使用的引用是一個非常糟糕的主意,無論它是在塊(第一個代碼)內還是在synchronized語句(第二個代碼)中直接執行。 讓它最終!哦,也不一定是null

相關問題