I am new to multi threading so would appreciate anyone's advice on whether I have done the right thing.
I need to do the following:
Pre process an incoming message and push it on << a data structure. I have used a HashMap with the UUID of the message as the key and the message itself as the value>> for random access. Any further requests for the status of this message, would send in the UUID which can then be retrieved from the Map for random access.
At the same time I need another thread, which would sequentially access the values(or the messages) in the order of insertion, and process them
So here's the first bit for manipulating the Map in a class Store
public class Store {
static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
static Map<String, MessageFileRead> fileGeneratorMap = Collections.synchronizedMap(new LinkedHashMap());
public static boolean insertRecord(MessageFileRead messageFileRead) {
boolean processed = false;
lock.writeLock().lock();
try {
if (!fileGeneratorMap.containsKey(messageFileRead.uuid)) {
fileGeneratorMap.put(messageFileRead.uuid, messageFileRead);
processed = true;
}
} finally {
lock.writeLock().unlock();
}
return processed;
}
public static boolean updateRecord(String uuid, Status status) {
boolean processed = false;
lock.writeLock().lock();
try {
if (fileGeneratorMap.containsKey(uuid)) {
fileGeneratorMap.get(uuid).status = status;
processed = true;
}
} finally {
lock.writeLock().unlock();
}
return processed;
}
public static boolean deleteRecord(String uuid) {
boolean processed = false;
lock.writeLock().lock();
try {
for (final Iterator<Map.Entry<String, MessageFileRead>> it = fileGeneratorMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, MessageFileRead> entry = it.next();
if (entry.getKey().equals(uuid)) {
it.remove();
break;
}
}
} finally {
lock.writeLock().unlock();
}
return processed;
}
This is the code for Sequential access into the map using the Iterator which sits in another thread in another class in the same package. This is within a method which is part of the framework code to invoke a new worker Thread.
while (!stopped) {
try {
Store.lock.writeLock().lock();
for (final Iterator<Map.Entry<String, MessageFileRead>> it = Store.fileGeneratorMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, MessageFileRead> entry = it.next();
MessageRead message = entry.getValue();
if (message.status != COMPLETED) {
JSONObject response = DbService.process(message);
// And the above process method internally calls the updateRecord with a status of COMPLETED so that this message is marked as COMPLETED processing and is not picked up in the next run.
}
}
} finally {
Store.lock.writeLock().unlock();
}
}
I haven't encountered any issues so far, but its still initial stages and I want to know if I have done the right thing, so any advice/suggestions are welcome.