【问题标题】:@singleton behaving like @stateless bean@singleton 表现得像 @stateless bean
【发布时间】:2014-05-05 10:29:06
【问题描述】:

我正在开发一个应用程序(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);

    }
}   

【问题讨论】:

    标签: java singleton ejb-3.1 stateless-session-bean


    【解决方案1】:

    垃圾收集: 如果一个单例类被垃圾收集,那么它会在需要时通过创建一个新实例再次重新加载。当没有对此类及其实例的引用时会发生这种情况;所有字段都被默认/重新初始化,并且之前的状态丢失了。

    类加载器:在多个类加载器的情况下,可以存在多个副本,每个副本都可以有自己的单例实例。


    在您的情况下,线程可能没有对单例类的任何引用,因为一旦它们完成,引用就会被销毁并且单例可能会被垃圾收集。

    由于默认情况下单例 bean 对容器管理并发的方法具有 WRITE 锁定,因此您无需为方法显式指定 LockType 为字段指定 volatile,因为一次只能访问一个客户端。

    您可以尝试将记录器添加到默认构造函数、启动和销毁方法,以了解其背后真正发生的事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      • 1970-01-01
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      相关资源
      最近更新 更多