2015-07-12 43 views
-1

CopyOnWriteArrayList的情況下,只要將元素添加到集合中就會創建一個新對象。CopyOnWriteArrayList - 如何更新堆棧?

考慮下面的例子:

private static void copyOnWriteArrayList() { 
    List<String> playersUsing2 = new CopyOnWriteArrayList<String>(); 
    System.out.println("Original hashCode = " + playersUsing2.hashCode()); 
    playersUsing2.add("a1"); 
    System.out.println("After a1 hashCode = " + playersUsing2.hashCode() + " size = " + playersUsing2.size()); 
    addElement(playersUsing2, "a2"); 
    System.out.println("After b1 from copyOnWriteArrayList hashCode = " + playersUsing2.hashCode() + " size = " + playersUsing2.size()); 
    playersUsing2.add("b1"); 
    System.out.println("After b1 hashCode = " + playersUsing2.hashCode() + " size = " + playersUsing2.size()); 
} 

private static void addElement(List<String> playersUsingNew, String value) { 
    playersUsingNew.add(value); 
    System.out.println("After a2 hashCode = " + playersUsingNew.hashCode() + " size = " + playersUsingNew.size()); 
} 

添加元素時每一次,一個新的對象將被創建,並且在堆棧上playersUsing2參考將被更新以指向該存儲器位置。可以理解的。

現在,我通過playersUsing2到另一種方法,所以一個新的堆棧幀將被創建,並且playersUsingNew也將指向相同的內存位置。並且,當添加新元素時,將創建新對象並且playersUsingNew將指向新的存儲器位置。

但是,如何更新第一個堆棧幀(playersUsing2)以指向最新的內存位置?

我看到java.util.concurrent.CopyOnWriteArrayList.add(E)的實現,但無法理解。它是通過一些本機代碼和JVM來處理的,它是如何發生的?

輸出:

Original hashCode = 1 
After a1 hashCode = 3087 size = 1 
After a2 hashCode = 98754 size = 2 
After b1 from copyOnWriteArrayList hashCode = 98754 size = 2 
After b1 hashCode = 3064461 size = 3 
+0

你是什麼意思_a將創建一個新的對象,並且'playersUsing2'參考stack_? –

+2

我認爲你誤解了語句_ java.util.ArrayList'的線程安全變體,其中所有可變操作(add,set等)都是通過創建**底層數組的新副本來實現的* * ._ –

+0

@SotiriosDelimanolis但是爲什麼每次變更操作之後我都會看到一個新的hashcode值。我添加了run的o/p。 – hagrawal

回答

0

那麼它是一種誤解斷定散列代碼變更表示創建的由hashCode()方法返回的新object.The值是沒有保證是的存儲器地址的裝置目的。

+0

「* hashCode()返回的值決不能保證是對象的內存地址。*」如果不覆蓋hashCode()',那麼通常情況下它是true。我已經想出了在'CopyOnWriteArrayList'和'ArrayList'的情況下,它被覆蓋。儘管感謝您的提示。 – hagrawal