簡體   English   中英

無狀態會話bean中的多線程?

[英]Multithreading in a stateless session bean?

EJB 3.0規范不允許無狀態會話bean的業務方法創建新線程。 這是為什么? 創建僅執行原始計算而從不調用應用服務器的附加工作線程有什么問題?

說,我的會話bean實現了一項服務,該服務允許用戶上傳圖像,而business方法對這些圖像進行CPU密集型圖像處理。 那么,即使機器有8個或更多內核,它也只能使用一個cpu內核來完成這項工作? 如果我利用第三方圖像處理庫在內部創建工作線程,那么即使該庫與這些線程與EJB容器完全無關,我也會違反EJB規范。 這似乎不正確。

如果我忽略EJB規則並仍然創建一些工作線程來執行cpu密集處理,會發生什么? 當然,這些線程永遠不會觸摸任何應用程序服務器對象,並且Bean線程會在返回之前將它們加入。 還會發生不好的事情嗎?

EJB 3.0規范不允許無狀態會話bean的業務方法創建新線程。 這是為什么?

簡短版:禁止從EJB管理線程,因為這會損害資源管理,事務管理,安全性(技術原因),並且因為這是EJB模型不希望推廣的(哲學原因)。

EJB規范如下所示:

21.1.2編程限制

...

  • 企業bean不得嘗試管理線程。 企業bean不得嘗試啟動,停止,掛起或恢復線程,也不能嘗試更改線程的優先級或名稱。 企業bean不得嘗試管理線程組。

這些功能是為EJB容器保留的。 允許企業bean管理線程將降低容器正確管理運行時環境的能力。

也可以看看

(...)如果我利用第三方圖像處理庫在內部創建工作線程,那么即使該庫與這些線程與EJB容器完全無關,我也會違反EJB規范。 這似乎不正確。

我能說什么,如果您不喜歡EJB,請不要使用。

如果我忽略EJB規則並仍然創建一些工作線程來執行cpu密集處理,會發生什么? 當然,這些線程永遠不會觸摸任何應用程序服務器對象,並且Bean線程會在返回之前將它們加入。 還會發生不好的事情嗎?

這些線程是否正在接觸應用服務器對象並不重要。 規則就是規則,您不想遵循它們,您是一個人,行為是不確定的。 某些容器可能更寬松,並且允許它使用,而另一些容器則不允許,您的應用程序不能移植,等等。但是仍然明確禁止使用。

如果要以標准方式“產生”線程,請使用WorkManager API或JMS。

相關問題

以我的簡化理解,這就像經營一家公司。 您是老板(容器),並且有一個雇員突然間突然雇用了100名員工,而沒有任何通知(豆子)。

但是您仍然可以使用@Asynchronous批注輕松進行多線程處理(還有其他方法)。

@Stateless
public class Employee {
    @Asynchronous
    public Future<Void> work(Project projectThatTakeTooLong) {
        // work work work
        return new AsyncResult<Void>(null);
    }
}

@Stateless
public class Boss {

    @Inject
    private Employee randomStatelessEmployee;

    public void giveWork() {
        Future<Void> result1 = randomStatelessEmployee.work(new Project());
        Future<Void> result2 = randomStatelessEmployee.work(new Project());
        Future<Void> result3 = randomStatelessEmployee.work(new Project());
        result1.get();
        result2.get();
        result3.get();
    }
}

這里還有一個更好的示例: Jboss Java EE容器和ExecutorService

一種解決方法:

import java.util.concurrent.Executor;
import javax.ejb.Asynchronous;
import javax.ejb.Stateless;

@Stateless
public class TransactionalExecutor implements Executor {

    @Override @Asynchronous
    public void execute(Runnable command) {
        command.run();
    }
}

現在,您可以將TransactionalExecutor用作執行程序:

@Stateless
public class SlowService {

    @Inject
    Executor command;

    public void invoke(){
        Runnable command = new Runnable() {
            @Override
            public void run() {
                // heavy task
            }
        };
        command.execute(command);
    }    
}

這是在J2EE應用程序中不使用線程的限制。 應用程序服務器應注意程序的並行執行

是的,您可以忽略EJB規則,但是可能會遇到極其不可預測的行為

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM