I'm using a thirdparty class in my J2EE application which writes encrypted file onto the file system. Its observed that its taking a long time when many users access the system. Tracing I found that its getting delayed in writing the file onto the hard drive. I investigated further that the third party class is using following code to write to file the byte data. I'm suspecting a delay in this block. I wish if the forum buddies throw some light on this:
Its affecting the system users since its a web application where this class is called and its giving a time delay of something like 2-3 minutes for each user. Any feedback is highly appreciated. Kindly suggest the recovery from this.
Why do you need to encrypt the data file and write to server? I mean the app server should be secured and you may save the file directly. Or you write an other bach job to do the encryting seperately. Hope it helps.
Thanks for your response. Actually its a thridparty software which is user to encrypt the user transaction. And my application - all it needs was to fetch this file which is created at each user transaction and store it in our DB as a blob. But when in real-time the system took almost around 4-5 mins for a user to complete a transaction, Tracing the process fund that writing these files on filesystem is taking the delay time and almost delay from user to do the transaction. But it does completes, does'nt fail.
My concern is what's in this block of code that might be delaying the whole process so much??
Well this is the only place where I have posted this request. I believe since the code block where i traced the issue was related to synchronized, so thought of posting on this thread. Pls. move to relevent thread if you are moderator and if u feel it belongs to J2EE.
All your threads are belong to us! I mean all concurrent users must go through this method single file. Ouch. Maybe the author didn't want 300 file handles open at once so he chose 1 as the next best answer.
If you can change the code and can tolerate one file handle per user at any given instant, try removing "synchronized" and let us know what happens.
If you think 20 was maybe a better answer than 300 or 1, it would be fun to put this method into a Runnable and throw a bunch in a thread pool. If by J2EE you meant Servlet and not EJB. In EJB it's not nice to play with your own threads.
In Servlet or EJB containers it's seriously not nice to synchronize this method!
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
The calls are occuring from session to session basis through the webapplication. So each session initiates this method, hence it doesnt conflict the transactions occuring concurrently and they are not writing onto the single file. Each session user file is written on filename which is the combination of timesstamp + username. So, even if i remove synchronized on writeFile it should'nt create the problem, right..?? & do you see the process of writing getting faster if i remove the synchronized??
As i said i'm poking at the codes of third party s/w, so dont know why they have this synchronized. Just trying to play around to resolve this huge delay in user transaction. Any feedback is appreciated.
Originally posted by Karan Sinha: So, even if i remove synchronized on writeFile it should'nt create the problem, right..?? & do you see the process of writing getting faster if i remove the synchronized??
Yes, that was exactly his point. It's not that the individual calls will get faster; it's that the individual calls won't have to wait for eachother anymore. Right now if there are 100 clients all trying to write a file at the same time, the synchronization means that on the average, a client has to wait for 50 other clients to write their files first. Therefore the measured time to write a file is 50 times the actual time!
The method is static 'private static synchronized void' so all the threads calling this method will try to acquire the Class level lock and hence only one thread will be able to write at a time even though these threads may belong to different session.
Removing synchronized will allow the threads to write the file without waiting. As per your description, only one thread will be writing to one file at a time .. so synchronized is not required here.
CLG, I'm a bit surprised. What happened to only syncing on private monitors? Also note that it's possible for two different strings to refer to the same file, e.g.
foo.txt ./foo.txt /a/b/foo.txt
And on Windows, case becomes insignificant, and Java may allow you to use either \ or / somewhat interchangeably. So there are numerous ways in which synchronizing on a String of the filename is unreliable. Instead, I would recommend using a Set of File instances, since File overrides equals() and hasCode() so that if two Files have different paths which evaluate to the same actual file, they are considered equal. Use it similar to what David Wingate does above - except again, I wouldn't sync on a String; I'd synchronize on the private consumedFileNames instance. And sync on the final remove() as well of course.