2010-07-09 45 views
15

我正在使用Struts和Spring編寫Java EE應用程序。在其中一項操作中,數據庫處理繁重,因此存在性能問題。我想知道的是我可以在這裏使用多線程嗎?我認爲Java EE規範不允許創建自定義線程,而不是由服務器創建的自定義線程(我使用Weblogic)。請通過這個指導我。Java EE規範和多線程

回答

5

這個問題偶爾會彈出一次。

根據規範,它沒有被授權。最好看的頁面是這一個:Q/A: J2EE Restrictions

也就是說,有辦法產生線程,特別是在Weblogic與WorkManager

看到這些問題:

的第一個目標EJB應該那麼重要的事實,和有關訪問的最後一個到文件系統是關於一般限制。

希望它有幫助。

4

這些限制主要是因爲Java EE和EJB想要支持透明集羣。例如,羣集中的一臺服務器不應修改文件,因爲這些更改無法輕鬆映射到其他服務器。對於線程來說,每個羣集或每個服務器是否應該有一個線程是個問題。這些線程也不能被應用程序服務器輕鬆監視。

也就是說,應該可以創建線程,套接字連接或訪問Java EE服務器中的文件系統,就像在普通應用程序中一樣。

45

在Java EE環境中創建線程的推薦方法是使用併發實用程序API,它是EE7規範的一部分。

通過使用此API,您的新線程將被創建並由容器管理,從而保證所有EE服務都可用於您的線程(例如安全性,事務)。

下面的例子來自我自己的網站herehere

使用ManagedExecutorService

創建使用ManagedExecutorService一個新的線程,首先創建一個實現可調用任務對象服用。在call()方法中,我們將定義我們想要在單獨的線程中執行的工作。

public class ReportTask implements Callable<Report> { 

    Logger logger = Logger.getLogger(getClass().getSimpleName()); 

    public Report call() { 
     try { 
      Thread.sleep(3000); 
     catch (InterruptedException e) { 
      logger.log(Level.SEVERE, "Thread interrupted", e); 
     } 
     return new Report(); 
    } 
} 

然後,我們需要通過將其雖然在ManagedExecutorService的提交()方法來調用任務。

@Stateless 
public class ReportBean { 

    @Resource 
    private ManagedExecutorService executorService; 

    public void runReports() { 
     ReportTask reportTask = new ReportTask(); 
     Future<Report> future = executorService.submit(reportTask); 
    } 
} 

使用ManagedThreadFactory

首先創建一個Runnable任務將定義哪些工作是在後臺完成。

public class ReportTask implements Runnable { 

    Logger logger = Logger.getLogger(getClass().getSimpleName()); 

    public void run() { 
     try { 
      //do your background task 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      logger.log(Level.SEVERE, "Thread interrupted", e); 
     } 
    } 
} 

要獲取一個容器管理的線程,我們簡單地問了ManagedThreadFactory一個新的線程,並把它傳遞我們的Runnable的實例。要開始我們稱之爲start()的線程。

@Stateless 
public class ReportBean { 

    @Resource 
    private ManagedThreadFactory threadFactory; 

    public void runReports() { 
     ReportTask reportTask = new ReportTask(); 
     Thread thread = threadFactory.newThread(reportTask); 
     thread.start(); 
    } 
} 
+0

@CRITCHIE,非常有用,謝謝! – Sid 2013-10-17 06:05:03

+0

遠比接受的答案更詳細和更好的記錄IMO – Jewels 2014-05-27 10:45:02

+2

@Jewels問題和接受的答案比這個答案有點老。這是一項新功能。 – dbreaux 2014-07-28 18:21:20