下面是示例代码来说明这种情况:
public class ConnectionRegistry {
private ConcurrentMap<String, List<Connection>> registry = new ConcurrentHashMap<>();
public List<Connection> find(String key) {
List<Connection> connections = registry.get(key);
if (null == connections) {
return Collections.emptyList();
}
synchronized(connections) {
return new ArrayList(originalCopy);
}
}
public void register(String key, Connection connection) {
List<Connection> connections = registry.get(key);
if (null == connections) {
List<Connection> newConnections = new ArrayList<>();
connections = registry.putIfAbsent(key, newConnections);
if (null == connections) {
connections = newConnections;
}
}
synchronized(connections) {
connections.add(connection);
}
}
}
在上面的代码中,我有一个注册表来管理按键索引的连接。我想让它线程安全,所以我使用了 ConcurrentMap 数据结构,除了 map 之外,我想确保 map 内的 List 也是线程的安全,因此我使用 synchronize
关键字,如上面的源代码所示。
但是我的 IDE 警告我,这是局部变量同步,并且使用此类同步时很难保证正确性。
有没有其他方法或好的做法来处理这种情况?
最佳答案
Vector 实现了动态数组。它与 ArrayList 类似,但有两点不同:
- vector 已同步。
- Vector 包含许多不属于集合框架的旧方法。
来自文档:
Unlike the new collection implementations, Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.
经过一些更改,代码将是:
public class ConnectionRegistry {
private ConcurrentMap<String, List<Connection>> registry = new ConcurrentHashMap<>();
public List<Connection> find(String key) {
List<Connection> connections = registry.get(key);
if (null == connections) {
return Collections.emptyList();
}
return new Vector<Connection>(originalCopy);
}
public void register(String key, Connection connection) {
List<Connection> connections = registry.get(key);
if (null == connections) {
List<Connection> newConnections = new Vector<Connection>();
connections = registry.putIfAbsent(key, newConnections);
if (null == connections) {
connections = newConnections;
}
}
connections.add(connection);
}
关于java - 同步 map 内的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43958679/