我有 1 个线程在 HashMap 中插入值,另一个线程仅通过 HashMap 读取值。我不知道为什么我无法读取正确的值。
我向你展示我做了什么:
通过主线程,我在 HashMap 中添加值:
public class S3Esercizio1 {
public static void main(final String[] args) {
final EventSource eventSource = new EventSource();
final Thread eventSourceThread = new Thread(eventSource);
// run the thread
eventSourceThread.start();
// create and register the EventListeners
final List<EventListener> allListeners = new ArrayList<>();
for (int i = 0; i < 20; i++)
allListeners.add(new EventListener(i, eventSource));
// Wait untill the other thread finish his job.
try {
eventSourceThread.join();
} catch (final InterruptedException e) {
// Thread interrotto
}
}
}
当创建一个新的EventListener时,调用这个构造函数:
public EventListener(final int id, final EventSource eventSource) {
eventSource.registerListener(id, this);
// this sleep simulate the problem
try {
Thread.sleep(4);
} catch (final InterruptedException e) {
// Thread interrupted
}
this.id = id;
}
通过 registerListener 方法,我将值插入到 HashMap 中
public synchronized void registerListener(final int id, final EventListener listener) {
allListeners.putIfAbsent(id, listener);
}
在另一个线程中有 HashMap ,通过这个线程,我读取 HashMap 中的值,而主线程(同时)在 HashMap 中插入值:
class EventSource implements Runnable {
final ConcurrentHashMap<Integer, EventListener> allListeners =
new ConcurrentHashMap<Integer, EventListener>();
@Override
public void run() {
for (long i = 0; i < 30000000; i++) {
final Event e = new Event(i);
final java.util.Iterator<Integer> it =
allListeners.keySet().iterator();
while(it.hasNext()) {
final Integer id = it.next();
EventListener listener = allListeners.get(id);
listener.onEvent(id, e);
}
}
}
public synchronized void registerListener(final int id, final EventListener listener) {
allListeners.putIfAbsent(id, listener);
}
}
什么时候调用onEvent方法:
public void onEvent(final int listenerID, final Event e) {
if (listenerID != id)
System.out.println("Inconsistent listener ID" + listenerID + " : "
+ e);
}
它检查我是否通过他的 id 在 HashMap 中获得了正确的监听器。
我不知道为什么不是!
这是输出:我只输入了一些行...但它会一直持续到最后一个 ID (20):
...
Inconsistent listener ID14 : Event: 3104
Inconsistent listener ID14 : Event: 3105
Inconsistent listener ID14 : Event: 3106
...
这真的很奇怪,因为我使用了:ConcurrentHashMap
,这样我就可以毫无问题地读取并同时编辑 HashMap ...
问题出在哪里?
最佳答案
Id 分配必须首先出现在 EventListener 的构造函数中。 EventListener 的实例在传递到另一个线程时具有未定义的状态。祝你好运!
关于Java多线程HashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22750989/