Re: Cannot seem to lock HashMap
Thanks for the reply - but I tried to synchronize on both HashMap
put() and clone() operations, and that still does not work (I still
get ConcurrentModificationException). Any ideas?
I was finally able to get something else working - although it is slow
(see final example at end of posting). This just uses the wrapper
class to do the locking, as the underlying Hashmap is not made public.
.... CHANGES ONLY MADE TO TestContainer class ...
public static class TestContainer {
private HashMap<Date, Date> _values;
public TestContainer() {
_values = new HashMap<Date, Date>();
}
public TestContainer(HashMap<Date, Date> v) {
_values = v;
}
private void put(Date key, Date value) {
Map<Date, Date> m = Collections.synchronizedMap(_values);
synchronized (m) {
m.put(key, value);
}
}
public Date get(Date key) {
return _values.get(key);
}
public Object clone() {
TestContainer eStore = null;
Map<Date, Date> m = Collections.synchronizedMap(_values);
synchronized (m) {
HashMap<Date, Date> cValues = new HashMap<Date, Date>(m);
m.remove(ITFGlobalID.GID_FLAG);
eStore = new TestContainer(cValues);
}
return eStore;
}
}
Also here is my final code, that DOES work, but is not ideal (seems to
run slow).
package com.sscims.casetracker;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.sscims.jeb.enterprise.ITFGlobalID;
public class TestIndex {
public static void main(String[] args) {
TestContainer c = new TestContainer();
new Thread_1(c).start();
new Thread_2(c).start();
}
public static class Thread_1 extends Thread {
TestContainer c;
public Thread_1(TestContainer c) {
super("Thread_1");
this.setDaemon(false);
this.c = c;
}
public void run() {
Date start = new Date();
System.out.println("Thread_1 run...");
try {
for (int i=0; i<1000000; i++) {
Date key = new Date();
c.put(key,new Date());
c.get(key);
}
} catch (Exception e) {
e.printStackTrace();
}
Date end = new Date();
long diff = end.getTime() - start.getTime();
System.out.println("Thread_1 END: " + diff + " total time");
}
}
public static class Thread_2 extends Thread {
TestContainer c;
public Thread_2(TestContainer c) {
super("Thread_2");
this.setDaemon(false);
this.c = c;
}
public void run() {
Date start = new Date();
System.out.println("Thread_2 run...");
try {
for (int i=0; i<1000000; i++) {
c.clone();
}
} catch (Exception e) {
e.printStackTrace();
}
Date end = new Date();
long diff = end.getTime() - start.getTime();
System.out.println("Thread_2 END: " + diff + " total time");
}
}
public static class TestContainer {
private HashMap<Date, Date> _values;
public TestContainer() {
_values = new HashMap<Date, Date>();
}
public TestContainer(HashMap<Date, Date> v) {
_values = v;
}
private synchronized void put(Date key, Date value) {
_values.put(key, value);
}
public Date get(Date key) {
return _values.get(key);
}
public synchronized Object clone() {
synchronized (this) {
HashMap<Date, Date> cValues = new HashMap<Date, Date>(_values);
cValues.remove(ITFGlobalID.GID_FLAG);
return new TestContainer(cValues);
}
}
}
}