【发布时间】:2014-06-24 03:16:25
【问题描述】:
我有以下课程(省略批量代码):
public class SimpleEventBus implements EventBus {
private final static Set<EventHandler> EMPTY_SET = Collections.emptySet();
private final static EventHandler[] EMPTY_ARRAY = new EventHandler[0];
private final static Supplier<Set<EventHandler>> CONCURRENT_SET_SUPPLIER =
() -> Collections.newSetFromMap(new ConcurrentHashMap<>());
private final ConcurrentMap<Class<?>, Set<EventHandler>> eventMapping = new ConcurrentHashMap<>();
private final Class<?> eventClassConstraint;
public SimpleEventBus() {
this(Object.class);
}
public SimpleEventBus(final Class<?> eventClassConstraint) {
this.eventClassConstraint = Objects.requireNonNull(eventClassConstraint);
}
...
@Override
public void executeEvent(final Object event) {
if (eventClassConstraint.isAssignableFrom(event.getClass())) {
getCopyOfEventHandlers(event.getClass()).forEach(eventHandler -> eventHandler.invoke(event));
}
}
...
private Stream<EventHandler> getCopyOfEventHandlers(final Class<?> eventClass) {
Set<EventHandler> eventHandlers = eventMapping.get(Objects.requireNonNull(eventClass));
return (eventHandlers == null)
? Stream.empty()
: Arrays.stream(eventHandlers.toArray(EMPTY_ARRAY));
}
...
}
我想知道这里的getCopyOfEventHandlers 是否仍然返回该集合的线程安全副本。我知道我会这样写:
private EventHandler[] getCopyOfEventHandlers(final Class<?> eventClass) {
Set<EventHandler> eventHandlers = eventMapping.get(Objects.requireNonNull(eventClass));
return (eventHandlers == null)
? EMPTY_ARRAY
: eventHandlers.toArray(EMPTY_ARRAY);
}
但我想尽可能地从 Java 8 中受益,因此我决定这样做:
private Stream<EventHandler> getCopyOfEventHandlers(final Class<?> eventClass) {
Set<EventHandler> eventHandlers = eventMapping.get(Objects.requireNonNull(eventClass));
return (eventHandlers == null)
? Stream.empty()
: Arrays.stream(eventHandlers.toArray(EMPTY_ARRAY));
}
由于流使用延迟初始化,这仍然是线程安全的吗?这是否意味着生成的数组(来自 eventHandlers.toArray(EMPTY_ARRAY) 被隐式存储在内存中(被 GC 阻止)?
【问题讨论】:
标签: java thread-safety java-8 java-stream