java - Java - 避免将对象引用传递给多个地方,同时确保其线程安全
问题描述
我有一个带有变量和方法的类,它基本上是一个跨多个类用于以字符串格式呈现信息(secretInfo)的实用程序类。
基本上,根据需要,调用实用程序类并更新 secretInfo。
我已经尝试创建一个静态变量 secretInfo 并且在入口点初始化并在多个地方进行更新。
上述解决方案的唯一缺点是这在多线程环境中可能不起作用,我想避免创建静态变量。
有没有办法避免创建静态变量,同时可以跨多个地方访问实用程序对象,而无需将对象引用从一个地方传递到另一个地方,同时确保它在多线程环境中工作。
公共类secretInfoUtility {
public static HashMap<String, String> secretInfo;
public static String renderInfo(HashMap<String, String> secretInfo) {
//secretInfo gets updated here
}
}
注意 - 想法是保持这个实用程序类与其他类松散耦合。
解决方案
如果这可能是不可变的,那么就这样做。尽可能选择不变性。在这种情况下,您要避免的问题是由于多个线程之间共享资源的更改而导致的内存不一致。您可以通过与共享资源创建发生前的关系来做到这一点。在这种情况下,共享资源是一个 Map ,它可以是一个 ConcurrentHashMap ,它将确保所有读取和写入在内部同步。
public final class SecretInfo {
private final ConcurrentMap<String, String> secretInfo;
public SecretInfo(ConcurrentMap<String, String> secretInfo) {
this.secretInfo = secretInfo;
}
public String reder() {
// convert map to String, doesnt need to be synchronized
}
public void update(Map<String, String> update) {
// atomically update the map
}
}
public class SecretInfoService {
private final SecretInfo secretInfo;
public SecretInfoService(SecretInfo secretInfo) {
this.secretInfo = secretInfo;
}
public SecretInfo getSecretInfo() {
return secretInfo;
}
}
示例用法;
class MyEntryPoint {
public static void main(String... args) {
ConcurrentMap<String, String> info = new ConcurrentHashMap<>();
info.put("hello", "world");
info.put("foo", "bar");
SecretInfoService service = new SecretInfoService(new SecretInfo(info));
ClassWithServiceDependency clazz = new ClassWithServiceDependency(service);
}
static final class ClassWithServiceDependency {
private final SecretInfoService service;
private ClassWithServiceDependency(SecretInfoService service) {
this.service = service;
}
void render() {
String rendered = service.render();
}
}
}
推荐阅读
- unity3d - 统一实现 2d 平台游戏房间系统的更好方法
- node.js - 循环遍历参数值 - NodeJS (Puppeteer)
- rust - 预期的单元类型 '()',找到 'enum std::option::Option'
- python - Python:第 13 行 - EOF 文件错误,所有语法都正确,但仍然显示 eof 错误,我不知道为什么
- ios - 获取 CBATTErrorDomain Code=6 The request is not supported error while writing value to peripheral
- google-cloud-firestore - Firestore 对多个文档的实时更新?
- ruby - Ruby 中的 gsub 到底是什么?
- javascript - 如何解决“无法读取未定义的属性'forEach'”错误
- xamarin.forms - 将值从页面传递到列表中的另一个页面
- python - Python 3.8 - 列表索引必须是整数或切片,而不是 dict