It is often insecure to synchronize a method that hold a lock while performing performs network transactions. Depending on the speed and reliability of the connection, synchronization held locks can stall the program indefinitely causing a huge performance hit. At other times, it can result in temporary or permanent deadlock.
If the JVM is operating on a platform that uses a file system that operates over the network, then file I/O might also suffer the same performance hits as networked I/O. If such a platform is in use, then file I/O to files over the network should also not be performed while locks are held.
Noncompliant Code Example
...
In this compliant solution, the synchronized method getPage()
is called from an unsynchronized method sendReplysendPage()
, to find the requested Page
in the pageBuff
array. After the Page
is retrieved, the method sendReplysendPage()
calls the unsynchronized method sendPagedeliverPage()
to deliver the Page
to the client.
Code Block | ||
---|---|---|
| ||
public boolean sendReplysendPage(Socket socket, String pageName) { // No synchronization Page targetPage = getPage(pageName); if(targetPage == null) return FAILURE; return sendPagedeliverPage(socket, targetPage); } private synchronized Page getPage(String pageName) { // Requires synchronization Page targetPage = null; for(Page p : pageBuff) { if(p.getName().equals(pageName)) { targetPage = p; } } return targetPage; } public boolean sendPagedeliverPage(Socket socket, Page page){ try{ // Get the output stream to write the Page to ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream()); // Send the Page to the client out.writeObject(page); } catch(IOException io){ // If recovery is not possible return FAILURE return FAILURE; } finally { out.flush(); out.close(); } return SUCCESS; } |
Risk Assessment
If synchronized
methods and statements contain a lock is held by a block that contains network transactional logic, temporary or permanent deadlocks may result.
...