2014-02-06 46 views
5

我已閱讀並heard了很多關於immutability好東西,所以我決定嘗試一下,在我的愛好項目之一。我將所有字段都聲明爲只讀,並且使所有通常會使對象發生變化的方法返回一個新的修改版本。如何以不可變的方式實現緩存?

它很好工作,直到我跑進入的情況下的方法應,由外部協議,返回有關的對象的特定信息,而不修改它,但在同一時間可以通過改變內部結構進行優化。特別是,tree path compression發生在union find algorithm中。

當用戶調用int find(int n),對象出現未修飾的外人。它在概念上表示同一個實體,但它的內部字段會發生變化以優化運行時間。

我如何在一個不變的方式實現這一點?

+2

我要說的是,如果你在一個線程安全的方式突變,它由一個局外人的檢測不到的,那麼它可以被認爲是不可變的。 – Joe

+0

@Joe但這樣我就必須自己保持線程安全。據我所知,不變性的美妙之處在於,我可以通過指定只讀關鍵字將其留給語言。 –

+0

但你說過你想改變它。如果您不以線程安全的方式執行此操作,您將失去不可變類型(線程安全)的好處之一。 – Joe

回答

2

簡答:您必須自己確保線程安全。

在場上readonly關鍵字給你已構建了包含這一領域的對象後場不能被修改的保險。 因此,您可以爲該字段唯一寫入的內容包含在構造函數中(或在字段初始化中),並且在構造對象之前不會發生方法調用讀取,因此線程安全性爲readonly

如果你想實現緩存,你打破了只有一個寫入發生的假設(因爲「緩存寫入」可以並且將在你讀取期間發生),因此在壞的情況下可能存在線程問題(認爲你是從文件中讀取行,兩個線程可以調用具有相同參數的find方法,但讀取兩條不同的行,因此得到不同的結果)。 你想要實現的是observational immutability。這related question about memoization可以幫助你一個優雅的答案。