我正在开发一个应用程序(java中的企业应用程序),其中我需要由多个线程同时共享的单个实例,我使用了 @singleton 。当每个用户登录时,通过调用 setTeleCallersDetails() 远程方法在电话呼叫者列表中设置一个值。但在某些时候,当登录的用户数量超过 15 时,@singleton 开始表现得像 @stateless bean,因为 setTeleCallersDetails() 开始在新的tellcaller 数组列表中添加值。任何人都可以告诉实际上如何解决这个问题
这是我的代码
@Singleton
@Startup
public class UserSessionBean implements UserRemote {
volatile List<UserDetails> user;
volatile List<UserDetails> telecallers;
volatile List notloggedlt;
/**
* Default constructor.
* @return
*/
@PostConstruct
private void startup() {
// TODO Auto-generated constructor stub
if(user == null){
user = new ArrayList<UserDetails>();
}
if(telecallers == null){
telecallers = new ArrayList<UserDetails>();
}
if(notloggedlt == null){
notloggedlt = new ArrayList();
}
}
public List<UserDetails> getUserDetails(){
return user;
}
public List<UserDetails> getTeleCallersDetails(){
return telecallers;
}
public List getNotKLoggedInUsersDetails(){
return notloggedlt;
}
@Lock(LockType.WRITE)
public void setUserDetails(UserDetails objUser){
if(!user.isEmpty()){
Collections.sort(user);
int location = Collections.binarySearch(user, new UserDetails(objUser.getUserId()));
if (location >= 0) {
user.remove(location);
}
}
user.add(objUser);
}
@Lock(LockType.WRITE)
public void removeUserDetails(String userId){
Collections.sort(user);
int location = Collections.binarySearch(user, new UserDetails(userId));
if (location >= 0) {
user.remove(location);
}
}
@Lock(LockType.WRITE)
public void removeTeleCallersDetails(String userId){
Collections.sort(telecallers);
int location = Collections.binarySearch(telecallers, new UserDetails(userId));
if (location >= 0) {
telecallers.remove(location);
}
}
@Lock(LockType.WRITE)
public void setNotKLoggedInUsersDetails(List notloggedusers){
this.notloggedlt = notloggedusers;
}
@Lock(LockType.WRITE)
public void setNotKLoggedInUserDetail(UserDetails objUser){
notloggedlt.add(objUser);
}
@Lock(LockType.WRITE)
public void setTeleCallersDetails(UserDetails objUser){
if(!telecallers.isEmpty()){
Collections.sort(telecallers);
int location = Collections.binarySearch(telecallers, new UserDetails(objUser.getUserId()));
if (location >= 0) {
telecallers.remove(location);
}
}
telecallers.add(objUser);
}
}
垃圾收集:如果单例类被垃圾收集,那么它会在需要时通过创建新实例再次重新加载。当没有对该类及其实例的引用时,就会发生这种情况;所有字段都被默认/重新初始化并且之前的状态丢失。
类加载器:如果有多个类加载器,则可以存在多个副本,并且每个副本都可以有自己的单例实例。
可能在您的情况下,线程不持有对单例类的任何引用,因为一旦完成,引用就会被销毁并且单例可能会被垃圾收集.
由于单例 bean 默认情况下具有WRITE
锁定容器管理并发的方法,不需要显式指定LockType
对于方法&volatile
对于字段,因为一次只有一个客户端可以访问。
您可以尝试将记录器添加到默认构造函数、启动和销毁方法中,以了解底层到底发生了什么。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)