0

I have 1 thread that insert values in my hash map and another thread that just read the value by the hashmap. I don't know why i have problem to read the correct value.

I show to you what i did:
By the main thread i add the value in the hash map:

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
        }
    }
}

when is created a new EventListener is called this constructor:

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;
    }

and by the registerListener method i insert the value in the hashmap

public synchronized void registerListener(final int id, final EventListener listener) {
        allListeners.putIfAbsent(id, listener);
    }

In the other thread there is the Hashmap, and by this thread i read the values inside in the hashmap while the main thread (at the same time) insert values in the 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);
    }
}

when is called onEvent method:

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

it check if i get the correct listner in the hashmap by his id.
And i don't know why is not!

this is the output: i put just some rows... but it continue until the last ID (20):

...
Inconsistent listener ID14 : Event: 3104
Inconsistent listener ID14 : Event: 3105
Inconsistent listener ID14 : Event: 3106
...

This is really strange, because i used a: ConcurrentHashMap so in this way i can read and at the same time edit the hashmap without problem...
where is the problem?

1 Answer 1

1

Id assignment must be first in constructor of EventListener. Instance of EventListener has undefined state when passing into another thread. Good luck!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.