2014-11-03 101 views
0

正如在documentation中所提到的,我在後臺運行一個後臺線程,無限次地使用1個實例進行一些連續的後臺處理。在google appengine後臺運行只有一個後臺線程

import com.google.appengine.api.ThreadManager; 
import java.util.concurrent.AtomicLong; 

AtomicLong counter = new AtomicLong(); 

Thread thread = ThreadManager.createBackgroundThread(new Runnable() { 
    public void run() { 
    try { 
     while (true) { 
     counter.doStuff() 
     Thread.sleep(10); 
     } 
    } catch (InterruptedException ex) { 
     throw new RuntimeException("Interrupted in loop:", ex); 
    } 
    } 
}); 
thread.start(); 

我已將此代碼綁定到_ah/start端點,以便在實例啓動後執行它。然而,當在本地服務器上運行時,我發現_ah/start請求在運行時會多次出現,並啓動多個此類線程。我一次只需要一個線程來減少後臺處理中的爭用。

有什麼辦法抓住現有的bg線程並檢查它的運行是否可以避免新的線程創建?

更新 上傳這個代碼到雲後,我還觀察到,每次_ah /啓動是在後臺調用它產生一個新的線程爲_ah /背景端點的一部分,並保持運行。以這種方式,如果我們不能阻止較早的線程,那麼會有很多線程一起運行。

+0

一種方法在類成員變量中標記時間,並在嘗試創建第二個線程時檢查它是否是最近的。 – SoulMan 2014-11-03 11:45:18

回答

1

後端實例可能不是您所需要的。

這是事情:你想在服務器上運行無限處理。後端並不意味着這一點。您可能需要考慮在計算引擎上爲該特定情況分配虛擬機。

後臺用於在後臺運行長操作。這些操作通常由用戶請求。你的情況是不同的,這就是爲什麼我會考慮虛擬機場景。

無論如何,特別是針對您遇到的問題,運行線程的實例實際上並未接收多個_ah/start請求。每個實例只收到其中一個請求。但是,系統試圖用多個_ah/start請求分離多個實例。我不知道爲什麼,但顯然有些事情是要求後端多次出現。

你可以做什麼來避免內存中的多個線程,只要一個線程運行,就在Memcache中添加一個標誌(這是所有後端共享的)。每次線程啓動時,檢查該標誌是否不存在。如果有,請不要啓動線程。

確保您還實施_ah/stop請求以從memcache中刪除該標誌。

希望這會有所幫助。

+0

謝謝。是的,我最終會去GCE一點點,但只是好奇這裏發生了什麼。你是對的_ah/start在雲中只被調用一次,即使是單個後端(在不同的端口上模擬),該開發服務器也可以多次調用該端點。現在我可能需要一種機制來確保一個新線程運行,以防一個線程由於某種原因突然停止。 – SoulMan 2014-11-04 03:58:07

+0

另外,正如我在問題的評論中提到的,我可以依靠類成員變量來設置標誌。我認爲將會有一個這樣的類實例被注入其衝刺。 – SoulMan 2014-11-04 04:02:14

+0

如果你有兩個實例在運行(每個實例都在處理一個線程),那麼第二個實例的類變量將不可見(它們將在不同的處理器中運行)。 Memcache是​​您唯一的解決方案。您的國旗可以是每3秒左右更新一次的時間戳。當你得到一個_ah /開始檢查標誌是否最近被更新了,如果沒有,你可以開始你的線程。如果它已更新,則知道還有另一個線程已經運行。 – svpino 2014-11-05 13:43:13