但是从EJB 3.1开始,我们可以为Singleton定义ConcurrencyManagementType.BEAN。根据EJB规范:
使用Bean Managed Concurrency demarcation,容器允许对Singleton进行完全并发访问 bean实例。 bean开发者有责任在必要时保护其状态 由于并发访问导致的同步错误。允许bean开发人员使用Java语言 为此目的,级别同步原语,例如synchronized和volatile。
因此,如果我想实现等待一分钟的方法,我可以在这样的Singleton中使用Thread.sleep(),或者使用wait()和timeout,因为它是同步原语,或者它仍然会被视为反模式?
答案 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()都会阻塞其他线程的休眠时间。