Reputation: 59
I am trying to create multiple output text data files based on the data present in the servlet request. The constraints to my servlet are that:
The code I have written is such that:
doGet
is not synchronized
Within doGet
I am creating a new thread pool (reason being that the calling application to my servlet would not send a next request until my servlet returns a response back - so I validate the request and return an instant acknowledgement back to get new requests)
Pass over all request data to the thread created in a new thread pool
I am using wait(60000)
. The problem is that the code produces files with correct threshold (of names) within a minute, but after the timeout of a minute, the files produced (a very few) have capacity exceeded for example, names more than what I have defined in the capacity.
I think it has something to do with the threads who when wake up are causing an issue?
My code is
if(!hashmap_dob.containsKey(key)){
request_count=0;
hashmap_count.put(key, Integer.toString(request_count));
sb1 = new StringBuilder();
sb2 = new StringBuilder();
sb3 = new StringBuilder();
hashmap_dob.put(key, sb1);
hashmap_firstname.put(key, sb2);
hashmap_surname.put(key, sb3);
}
if(hashmap_dob.containsKey(key)){
request_count = Integer.parseInt(hm_count.get(key));
request_count++;
hashmap_count.put(key, Integer.toString(request_count));
hashmap_filehasbeenprinted.put(key, Boolean.toString(fileHasBeenPrinted));
}
hashmap_dob.get(key).append(dateofbirth + "-");
hashmap_firstname.get(key).append(firstName + "-");
hashmap_surname.get(key).append(surname + "-");
if (hashmap_count.get(key).equals(capacity)){
request_count = 0;
dob = hashmap_dob.get(key).toString();
firstname = hashmap_firstname.get(key).toString();
surname = hashmap_surname.get(key).toString();
produceFile(required String parameters for file printing);
fileHasBeenPrinted = true;
sb1 = new StringBuilder();
sb2 = new StringBuilder();
sb3 = new StringBuilder();
hashmap_dob.put(key, sb1);
hashmap_firstname.put(key, sb2);
hashmap_surname.put(key, sb3);
hashmap_count.put(key, Integer.toString(request_count));
hashmap_filehasbeenprinted.put(key, Boolean.toString(fileHasBeenPrinted));
}
try{
wait(Long.parseLong(listenerWaitingTime));
}catch (InterruptedException ie){
System.out.println("Thread interrupted from wait");
}
if(hashmap_filehasbeenprinted.get(key).equals("false")){
dob = hashmap_dob.get(key).toString();
firstname = hashmap_firstname.get(key).toString();
surname = hm_surname.get(key).toString();
produceFile(required String parameters for file printing );
sb1 = new StringBuilder();
sb2 = new StringBuilder();
sb3 = new StringBuilder();
hashmap_dob.put(key, sb1);
hashmap_firstname.put(key, sb2);
hashmap_surname.put(key, sb3);
fileHasBeenPrinted= true;
request_count =0;
hashmap_filehasbeenprinted.put(key, Boolean.toString(fileHasBeenPrinted));
hashmap_count.put(key, Integer.toString(request_count));
}
If you have got to here, then thank you for reading my question and thanks in advance if you have any thougths on it towards resolution!
Upvotes: 4
Views: 3111
Reputation: 5326
I tried to read your code, but there is a lot of information missing, so if you could please give more details:
1) the indentation is messed up and I'm not sure if there were some mistakes introduced when you copied your code.
2) What is the code you are posting? The code that is called on some other thread after by doGet?
3) Maybe you could also add the variable declarations. Are those thread safe types (ConcurrentHashMap)?
4) I'm not sure we have all the information about fileHasBeenPrinted. Also it seems to be a Boolean, which is not thread safe.
5) you talk about "synchronized" functions, but you did not include those.
EDIT:
If the code you copied is a synchronized method, that means if you have many requests, only one of them only ever runs at a given time. The 60 seconds waiting is always invoked it seems (it is not quite clear with the indentation, but I think there is always a 60 seconds wait, whether the file is written or not). So you lock the synchronized method for 60 seconds before another thread (request) can be processed. That could explain why you are not writing the file after 20 requests, since more than 20 requests can arrive within 60 seconds.
Upvotes: 1
Reputation: 328594
I didn't look at your code but I find your approach pretty complicated. Try this instead:
Create the thread and the queue in a ServletContextListener
. Interrupt the thread to stop it. In the thread, flush the last remaining items to the file when you receive an InterruptedException
while waiting on the queue.
Upvotes: 4
Reputation: 1561
As per my understanding, you want to create/produce a new file in two situations:
I would suggest following:
Upvotes: 1