Reputation: 1653
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?
Upvotes: 0
Views: 198
Reputation: 66
Id assignment must be first in constructor of EventListener. Instance of EventListener has undefined state when passing into another thread. Good luck!
Upvotes: 1