2017-08-23 59 views
1

我創建了一個Cache對象,它存儲String作爲鍵和一個序列化對象作爲值。多個線程可以使用同一CacheManager的相同Ehcache對象嗎?

Cache(String--->Object) 

我想運行三個Akka線程,它們以同步方式檢索並寫入同一個Ehcache對象。

Thread 1- synchronized (LockForEhcache){ 
       serializedObj = cachename.get("key"); //--- this returns an Object    
      } 
      //modify the serializedObj here.... 
      //Again store the modify Object in the Cache 
      synchronized (LockForEhcache){ 
       cachename.clear(); 
       cachename.put("key",serializedObj); 
Thread 2- synchronized (LockForEhcache){ 
       serializedObj = cachename.get("key"); //--- this returns null 
      } 
Thread 3- synchronized (LockForEhcache){ 
       serializedObj = cachename.get("key"); //--- this returns null 
      } 

但是隻有一個線程獲取存儲在Cache中的值。對於其餘的線程,它會拋出一個NullPointerException。我無法弄清楚爲什麼。

+0

不知道這些「同步(LockForEhcache)」是關於什麼......但ehcache不需要你同步訪問,它完全是線程安全的使用...如果,另一方面,你試圖同步這些線程,以便線程1在t2和t3進入'get'之前放置,這將不起作用。或者只是說你做了一些事情? –

+0

我正在使用鎖定,以便其他線程不會嘗試**取得**,除非線程1完成其**放**。爲什麼這不起作用? – Sibani

+0

好吧,也許我在這裏「猜測」太多...... t1是主線程,t2和t3是從那裏分離出來的?如果沒有,並且所有三個線程正在爭奪鎖,那麼這個_might_工作,但不確定性(即,你沒有保證t1首先獲取鎖並安裝映射)。 如果t1派生出另外兩個線程,它在安裝映射之後還需要這樣做。鎖只提供排除,而不是排序。 –

回答

2

首先,緩存不是商店。所以你不能指望緩存一直返回最新的數據。由於不同的原因,它可能會返回null。

現在,除非發生一些驅逐或到期,數據應該在那裏。所以我需要一個完整的例子來告訴你發生了什麼。

我的第一個問題是:你爲什麼要清理和放?爲什麼不只放?我們是否同意明確將清除所有條目?您的緩存中只有一個條目?

+0

在這裏,清除將刪除存儲在緩存中的所有條目並存儲最新的條目。因此,每次只有一個條目將出現在緩存中。 – Sibani

+0

爲什麼不只是覆蓋它們?你需要這是原子嗎? (完全替換同步) – Henri

+0

是的,我現在覆蓋,而不是清除。 – Sibani

1

我現在只看到第一個線程也以get開頭,那麼這是否意味着映射安裝了總是?如果是這樣,你確定其他線程實際上使用相同的Cache實例嗎?

+0

是的,所有線程都使用相同的**緩存實例**。你能否更詳細地說明安裝映射的含義? 這是否意味着,一旦我從** Cache **獲取**,我對該序列化對象所做的所有更新都將存儲在緩存中,而不使用** put **? – Sibani

+0

如果您存儲(不可變的)序列化表單,則不會。什麼都不會自動更新。另一方面,如果你存儲實際的可變對象,那麼......取決於:只要引用是on-heap(即它取決於你的緩存的拓撲和可能的時間),那麼對象_may_的任何改變根據JMM的看法,其他線程可見。 'put'將引入一個與'get'相關的密鑰。 –

+0

如果引用是在磁盤上會發生什麼? – Sibani

相關問題