2017-06-04 80 views
0

我的單例稱爲資源。它只能由我用這個標準辛格爾頓一次實例:單例在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://stackoverflow.com/a/4132721/3586783)瞭解更多信息。 – pacifier21

+0

我實際上已將部署更改爲.war文件,但仍然存在。 –

回答

0

去最好的辦法是讓編譯器爲您處理:

/** 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. 
}