EJB Singleton中的Thread.sleep()与ConcurrencyManagementType.BEAN

时间:2015-03-19 11:41:41

标签: multithreading java-ee concurrency singleton ejb

EJB bean中的 Thread.sleep()被认为是反模式Thread.sleep() in an EJB,因为“你不应该创建或管理线程”

但是从EJB 3.1开始,我们可以为Singleton定义ConcurrencyManagementType.BEAN。根据EJB规范:

使用Bean Managed Concurrency demarcation,容器允许对Singleton进行完全并发访问 bean实例。 bean开发者有责任在必要时保护其状态 由于并发访问导致的同步错误。允许bean开发人员使用Java语言 为此目的,级别同步原语,例如synchronized和volatile。

因此,如果我想实现等待一分钟的方法,我可以在这样的Singleton中使用Thread.sleep(),或者使用wait()和timeout,因为它是同步原语,或者它仍然会被视为反模式?

2 个答案:

答案 0 :(得分:1)

EJB 3.1规范说:

  

企业bean不得尝试管理线程。企业bean不得尝试   启动,停止,暂停或恢复线程,或更改线程的优先级或名称。进入 -   奖金bean不得试图管理线程组。

使用Thread.sleep(),即使bean使用ConcurrencyManagementType.BEAN进行注释,您仍会破坏上述规则。

Thread.sleep()可以通过注入托管执行程序服务在托管线程中使用。像这样:

    @Stateless
    public class ManagedThread {

    @Resource
    ManagedExecutorService executor;

        public void executeManagedThread(){
            Runnable task = () -> {
                try {
                    // some long running task
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            };
            executor.execute(task);
        }

    }

ConcurrencyManagementType.BEAN对于管理单例bean中的并发访问非常有用。例如,并发访问在读取和写入某些资源方面有所不同。更多信息可以在http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html找到。

答案 1 :(得分:1)

EJB规范引用:

  

企业bean不得尝试管理线程。企业bean不得尝试启动,停止,暂停或恢复线程,或更改线程的优先级或名称。企业bean不得尝试管理线程组。

因此规范明确表示不调用方法start(),stop(),suspend()和resume()。 它没有说出关于sleep()或wait()的任何内容,我会说,认为这些方法也被禁止是一种过度解释。

所以sleep()应该没有问题,并且使用bean管理并发,甚至可以阻止其他线程。 不过我想知道为什么你需要睡觉,但这是一个不同的问题。

对于wait(),您需要一个带监视器的同步块,并且根据您选择的对象,您可能会阻止其他线程。 您可能希望拥有互斥代码,这取决于您的使用案例。

使用容器管理的concurreny,sleep()和wait()都会阻塞其他线程的休眠时间。