单例在Glassfish服务器中实例化两次

问题描述:

我的单例称为资源。它只能由我用这个标准辛格尔顿一次实例:单例在Glassfish服务器中实例化两次

package site.kevindhu.models; 
 

 
import site.kevindhu.entity.Player; 
 

 
import java.util.HashMap; 
 
import java.util.HashSet; 
 
import java.util.Map; 
 

 
public class Resources { 
 
    public static Resources resources; 
 
    public Map<String, Object> data; 
 

 
    static { 
 
     resources = new Resources(); 
 
    } 
 

 
    private Resources() { 
 
     data = new HashMap<>(); 
 
     data.put("players", new HashSet<Player>()); 
 
     data.put("newPlayers", new HashSet<Player>()); 
 
    } 
 

 

 
    public static Resources getInstance() { 
 
     return resources; 
 
    } 
 
}

但是,它不能正常工作!

当我部署的.ear运行我的GlassFish服务器,它进入该块两次:

static { 
 
     resources = new Resources(); 
 
    }

其结果是,在“单身”其实每个创建两个不同的资源我运行服务器的时间。

我知道我做了两次,因为我调试时会调用两个不同的Resources对象,只要我尝试调用Resources.resources。

这可能是因为我正在部署一个.ear文件?这个双重实例化的具体细节如何工作?

+0

最有可能你的类过得去不同的类加载器加载。根据你写的内容,像这样的自定义单例可能不是应用服务器中最好的想法。 – pvg

+0

我也建议这是一个类加载器问题。 EAR中是否有多个WAR文件?每个人都可能拥有自己的ClassLoader,因此是一个单独的资源实例。请参阅[此答案](https://*.com/a/4132721/3586783)了解更多信息。 – pacifier21

+0

我实际上已将部署更改为.war文件,但仍然存在。 –

去最好的办法是让编译器为您处理:

/** Singleton. */ 
public enum Resources { 
    RESOURCES; 

    private final Map<String, Team> teams = new HashMap<>(); 

    public boolean add(Team team) { 
    return team != null 
     && teams.put(team.getName(), team) == null; 
    } 

    public Team find(String name) { 
    return name == null ? null : teams.get(name); 
    } 

    public Team find(Team team) { 
    return team == null ? null : get(team.getName()); 
    } 

    public Map<String, Team> getTeams() { 
    return Collections.unmodifiableMap(teams); 
    } 

    // remove, iterators, etc. 
} 

public class TeamImpl implements Team { 
    private final String name; 
    private final Map<String, Player> roster = new HashMap<>(); 

    public TeamImpl(String name) { 
    if (name == null) { 
     throw new IllegalArgumentException("name must not be null"); 
    } 
    this.name = name; 
    assert this.name != null; 
    } 

    @Override 
    public boolean equals(Object other) { 
    // base comparison on team name 
    } 

    @Override 
    public int hashCode() { 
    assert this.name != null; 
    return name.hashCode(); 
    } 

    // methods from interface Team: 

    @Override 
    public String getName() { 
    return name; 
    } 

    @Override 
    public Set<Player> getRoster() { 
    return Collections.unmodifiableSet(new HashSet<>(roster.values())); 
    } 

    @Override 
    public boolean add(Player player) { 
    return player != null 
     && roster.put(player.getName(), player) == null; 
    } 

    @Override 
    public Player find(String name) { 
    return name == null ? null : roster.get(name); 
    } 

    // remove, iterators, etc. 
}