首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java多线程HashMap

Java多线程HashMap
EN

Stack Overflow用户
提问于 2014-03-30 22:54:40
回答 1查看 179关注 0票数 0

我有一个线程在我的哈希映射中插入值,另一个线程通过hashmap读取值。我不知道为什么我有问题来读取正确的值。

我向你展示我所做的:

通过主线程,我在散列映射中添加了值:

代码语言:javascript
复制
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时,称为此构造函数:

代码语言:javascript
复制
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中插入了值

代码语言:javascript
复制
public synchronized void registerListener(final int id, final EventListener listener) {
        allListeners.putIfAbsent(id, listener);
    }

在另一个线程中有Hashmap,通过这个线程,我读取了hashmap中的值,而主线程(同时)在hashmap中插入值:

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
public void onEvent(final int listenerID, final Event e) {
    if (listenerID != id)
        System.out.println("Inconsistent listener ID" + listenerID + " : "
                + e);
}

它检查我是否通过他的id在hashmap中得到正确的listner。

我不知道为什么不是!

这是输出:我只放了几行..。但它一直持续到最后一个ID (20):

代码语言:javascript
复制
...
Inconsistent listener ID14 : Event: 3104
Inconsistent listener ID14 : Event: 3105
Inconsistent listener ID14 : Event: 3106
...

这真的很奇怪,因为我使用了一个:ConcurrentHashMap,这样我就可以阅读并同时编辑hashmap而没有问题.

问题出在哪里?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-31 01:17:11

在EventListener的构造函数中,必须首先分配Id。当传递到另一个线程时,EventListener实例具有未定义的状态。祝好运!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22750989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档