2017-02-15 65 views
0

我試圖避免在onStartMethod中使用同步映射執行服務上的重複任務,然後檢查密鑰是否尚未存儲。但是,到目前爲止,它不工作,如果我打電話快兩次啓動服務,它會執行相同的事情兩次。onStartCommand服務中的同步映射

public void onCreate() { 
      SYNCED_TABLES = Collections.synchronizedMap(new Hashtable<>()); 
} 
public int onStartCommand(Intent intent, int flags, int startId) { 
      synchronized (SYNCED_TABLES){ 
       if(!SYNCED_TABLES.containsKey(intent.getStringExtra(KEY))){ 
        SYNCED_TABLES.put(intent.getStringExtra(KEY), true); 
        /* Do stuff on a Handler thread */ 
       } 
       else{ 
        Log.d(TAG, "Tried to execute the same task twice " + intent.getStringExtra(KEY)); 
       } 
      } 

} 
+0

爲什麼不只是使用IntentService? – Submersed

+0

線程處理程序中完成的工作是對服務器的發佈請求。我們想要使請求多線程(有幾個不同的數據庫) – Julio

回答

0

SYNCED_TABLES的初始化不是線程安全的。因此,您可能有多個對象分配給您鎖定的該字段,即您有多個鎖。

申報SYNCED_TABLES作爲final場並初始化它的權利有:

public class Foo { 
    final SYNCED_TABLES = Collections.synchronizedMap(new Hashtable<>()); 
} 

這樣可以保證你在你的對象的生命週期單鎖。

+0

它的工作原理,但是,服務死後,地圖是否被再次實例化?因爲我只是試圖在幾分鐘後再次運行服務,並且因爲舊值仍然存儲而未執行。 – Julio

+0

有https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#clear()清空集合。你可以在'onCreate()'中調用它,如果這符合你的需求的話。 – aha

+0

謝謝,它現在有效 – Julio