2014-12-10 57 views
3

我是JSF中的新成員,我需要爲Google地圖使用線程。我正在使用谷歌地圖的primefaces,但我需要在後臺執行一個線程來從數據庫中獲取緯度和長度,然後在地圖上繪製標記。JSF中的線程?

回答

1

JSF是完全無關到您的問題。對於這種情況,JSF將充當純粹的HTML生成器。您的具體問題是如何異步準備數據並從您的Web應用程序中使用它。

您可以手動創建線程應用程序啓動時就實現ServletContextListener接口,像這樣一類:

public class ApplicationListener implements ServletContextListener { 
    ExecutorService executor; 

    public ApplicationListener() { 
     executor = Executors.newSingleThreadExecutor(); 
    } 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
     Runnable task = new Runnable() { 
      @Override 
      public void run() { 
       //process the data here... 
      } 
     } 
     executor.submit(task); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent sce) { 
     executor.shutdownNow(); 
    } 
} 

提高上述設計,以滿足您的要求。考慮到如果你知道你在做什麼,應該只在上創建應用程序服務器中的線程。

另一個實現是使用另一個應用程序來執行處理(我們稱之爲數據處理器),默認情況下它將在單獨的線程和環境中運行。然後,通過緩存或nosql應用程序(如EhCache,Infinispan或Hazelcast)將您的Web應用程序與此數據處理器進行通信。

2

你的問題是不特定於JSF,而是在一般的Web應用程序。那麼,如何在Java Web應用程序中異步執行任務?絕對不是通過創建自己的線程。

Java Web應用程序中的應用程序服務器(例如JBOSS)運行。應用程序服務器負責爲您管理Java線程。例如,它將爲每個進入的Web請求使用一個單獨的線程。應用程序服務器創建一個線程池並重用這些線程,因爲始終創建新線程的代價有點昂貴。這就是爲什麼你不應該創建自己的,特別是如果它完成每個Web請求,因爲它會直接影響可伸縮性。

爲了異步執行任務,可以使用ejb @Asynchronous註釋(假設應用程序運行在Java EE容器(如jBoss,但不是Tomcat)中)。

import javax.ejb.Singleton; 

@Singleton 
public class AsyncBean { 

    @Asynchronous 
    public void doSomethingAsynchronously() { 
     // when this EJB is injected somewhere, and this method is called, it will return to the caller immediately and its logic will run in the background 
    } 

} 

如果應用程序沒有在Java EE容器中運行,看看this answer這很好地勾畫出異步處理Web應用程序的一些其他的選擇。