Java 具有多线程和实例共享的泛型
我有一个泛型类,可以这样画Java 具有多线程和实例共享的泛型,java,generics,garbage-collection,Java,Generics,Garbage Collection,我有一个泛型类,可以这样画 public class Shared<T extends EntityBase> { private HashMap<String, Class<? extends Executor<T>>> classes; private HashMap<String, ? super Executor<T>> instances; private List<Entity&g
public class Shared<T extends EntityBase> {
private HashMap<String, Class<? extends Executor<T>>> classes;
private HashMap<String, ? super Executor<T>> instances;
private List<Entity> entities;
private Compiler compiler;
// Constructor and getters
public void put(Entity entity, Source source) {
Class<?> cls = compiler.load(source);
put(entity, (Class<? extends Executor<T>>) cls );
}
private void put(Entity entity, Class<? extends Executor<T>> cls) throws IllegalAccessException, InstantiationException {
classes.put(entity.getId(), cls);
instances.put(entity.getId(), cls.newInstance());
entities.add(entity);
}
}
公共类共享{
私有HashMap cls=compiler.load(源代码);
put(entity)(Class泛型实际上只是编译器想象的一部分;在运行时这一切都消失了。因此,本例中的泛型与您所看到的完全无关
粘贴的代码无法产生您看到的效果(贴图先更改,然后恢复)。但是,更一般地说,如果您从不同线程调用“put”,则此代码将被破坏。没有防止同步访问的保护措施。当您从不同线程同时更新映射时,映射规范特别指出任何情况都可能发生(从这个意义上说,仅仅重置为空的映射在技术上是“根据规范”的,因为您没有正确处理线程问题,所以任何事情都是允许的)
简单的解决方法是将第二个put方法标记为“synchronized”
另一种策略是使用java.util.concurrent
包中的列表和映射。但是,再多的使用都不会让您拥有类
,实例
和实体
保证彼此同步。只有同步
才能做到这一点。e标记为synchronized
,我将HashMaps
替换为ConcurrentHashMaps
。另一个变化是和ConcurrentHashMaps
的键现在都是实体
实例,而不是字符串
实例。现在这个共享
实例没有松动在两个ConcurrentHashMaps
中都取消它的对象
。不确定它是否以某种奇怪的方式与字符串池
相关。感谢您的关注though@JorgeLav这已经得到了回答。您的原始代码被破坏了,因为它不是线程安全的。它与泛型无关,与garba无关ge集合,没有字符串池。只有多线程。