Java ConcurrentHashMap的使用
我正在尝试用java创建一个映射,其中键和值是指定的: Key=类DataSourceCredentials的对象Java ConcurrentHashMap的使用,java,multithreading,concurrenthashmap,Java,Multithreading,Concurrenthashmap,我正在尝试用java创建一个映射,其中键和值是指定的: Key=类DataSourceCredentials的对象 public class DataSourceCredentials { String dataSourceName; char[] password; List<String> clusterNodes; } 公共类数据源目录{ 字符串数据源名称; char[]密码; 列出clusterNodes; } 值=类DataSourceConnector的对象 publ
public class DataSourceCredentials {
String dataSourceName;
char[] password;
List<String> clusterNodes;
}
公共类数据源目录{
字符串数据源名称;
char[]密码;
列出clusterNodes;
}
值=类DataSourceConnector的对象
public class DataSourceConnector {
private static volatile ConcurrentMap<DataSourceCredentials, DataSourceConnector> map = new ConcurrentHashMap<DataSourceCredentials, DataSourceConnector>();
}
公共类数据源连接器{
私有静态volatile ConcurrentMap=新ConcurrentHashMap();
}
DataSourceRedentials的equals方法检查dataSourceName和clusterNodes,但不检查密码。这是因为数据源的密码可以更改
我已经为类DataSourceConnector创建了下面的getInstance()方法,以便对于DataSourceRedentials的单个值,只创建并返回DataSourceConnector的一个实例
publicstaticdatasourceconnector getInstance(列出clusterNodes、stringdatasourcename、char[]密码){
试一试{
DataSourceCredentials dataSource=新的DataSourceCredentials(clusterNodes、dataSourceName、password);
//检查DataSourceConnector是否已存在,然后返回相同的值
对于(DataSourceCredentials dataSourceCredential:map.keySet()){
if(dataSourceCredential.equals(dataSource)){
if((password==null&&dataSourceCredential.getPassword()==null)| |(password!=null)
&&dataSourceCredential.getPassword()!=null&&array.equals(密码,dataSourceCredential.getPassword())){
返回map.get(dataSourceCredential);
}
}
}
DataSourceConnector连接器=map.get(dataSource);
//如果尚未创建DataSourceConnector,则创建一个并返回
if(连接器==null)
{
DataSourceConnector连接器=新的DataSourceConnector();
返回访问器.putIfAbsent(数据源、连接器);
}
else//如果DataSourceConnector存在,但密码已更改/删除/添加,则创建新的连接器并返回
{
已同步(DataSourceConnector.class)
{
对于(DataSourceCredentials dataSourceCredential:map.keySet()){
if(dataSourceCredential.equals(dataSource)&((password==null&&dataSourceCredential.getPassword()!=null)
||(!Arrays.equals(password,dataSourceCredential.getPassword())){
map.remove(dataSourceCredential);
DataSourceConnector连接器=新的DataSourceConnector();
返回map.putIfAbsent(数据源、连接器);
}
}
}
}
}
最后{
if(密码!=null){
数组。填充(密码“\0”);
}
}
返回null;
}
是否有人能建议上述实现是否可行,是否有更好的方法 你的equals方法行不通。您需要重写DataSourceRedentials类中的equals和hashcode方法。看这个,是的,我已经做了。
public static DataSourceConnector getInstance(List<String> clusterNodes, String dataSourceName, char[] password) {
try {
DataSourceCredentials dataSource = new DataSourceCredentials(clusterNodes, dataSourceName, password );
//check if DataSourceConnector already exists then return the same
for (DataSourceCredentials dataSourceCredential : map.keySet()) {
if (dataSourceCredential.equals(dataSource)) {
if ((password == null && dataSourceCredential.getPassword() == null) || (password != null
&& dataSourceCredential.getPassword() != null && Arrays.equals(password, dataSourceCredential.getPassword()))) {
return map.get(dataSourceCredential);
}
}
}
DataSourceConnector connector = map.get(dataSource);
//if DataSourceConnector has not not been created then create one and return
if(connector==null)
{
DataSourceConnector connector = new DataSourceConnector();
return accessors.putIfAbsent(dataSource,connector);
}
else //if DataSourceConnector exists but password has changed/removed/added then create a new connector and return
{
synchronized(DataSourceConnector.class)
{
for (DataSourceCredentials dataSourceCredential : map.keySet()) {
if (dataSourceCredential.equals(dataSource) && ((password == null && dataSourceCredential.getPassword() != null)
|| (!Arrays.equals(password, dataSourceCredential.getPassword())))) {
map.remove(dataSourceCredential);
DataSourceConnector connector = new DataSourceConnector();
return map.putIfAbsent(dataSource, connector);
}
}
}
}
}
finally {
if (password != null) {
Arrays.fill(password, '\0');
}
}
return null;
}