Meaningless Drivel is fun!*
The moose likes Servlets and the fly likes Synchronizing on a static method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "Synchronizing on a static method" Watch "Synchronizing on a static method" New topic
Author

Synchronizing on a static method

Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
I need to synchronize a method across all instances of my servlet. I think declaring the method as static and synchronized would accomplish this. But is there anything I'm overlooking?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

What would be the point of making the method static? That's just a bad design decision in support of an unrelated requirement. Just find some single object to synchronize on -- perhaps the class of your servlet would do, or if that's too un-obvious then put an object into application scope and synchronize on that.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
I can't get a clear answer anywhere on whether or not the J2EE container will load more than 1 object of a servlet at once. Because if it does synchronize by itself becomes useless. I've read through part of the specification for Servlet 2.4 here: http://download.oracle.com/otn-pub/jcp/servlet-2.4-fr-spec-oth-JSpec/servlet-2_4-fr-spec.pdf


SRV.2.2 Number of Instances

The servlet declaration which is part of the deployment descriptor of the Web application
containing the servlet, as described in Chapter SRV.13, “Deployment
Descriptor”, controls how the servlet container provides instances of the servlet.
For a servlet not hosted in a distributed environment (the default), the servlet
container must use only one instance per servlet declaration. However, for a servlet
implementing the SingleThreadModel interface, the servlet container may
instantiate multiple instances to handle a heavy request load and serialize requests
to a particular instance.
In the case where a servlet was deployed as part of an application marked in
the deployment descriptor as distributable, a container may have only one instance
per servlet declaration per Java Virtual Machine (JVMTM). However, if the servlet
in a distributable application implements the SingleThreadModel interface, the
container may instantiate multiple instances of that servlet in each JVM of the
container.


Are they saying the default is a servlet not hosted in a distributed environment or the other way around? And how is the term instance defined here? I can't understand from the documentation whether there is more than 1 object of a servlet alive at once.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

I would expect the word instance to have its standard object-oriented meaning.

I read that as "One instance per JVM unless SingleThreadModel, in which case maybe more than one instance per JVM". Is your requirement to synchronize this method across instances in more than one JVM?
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
I'm only running in 1 JVM. In the past I have read here on this forum that keeping more than 1 instance per servlet was not a requirement for a J2EE container so that's why I've been digging into the spec to see if I can figure this out.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Rob Micah wrote:In the past I have read here on this forum that keeping more than 1 instance per servlet was not a requirement for a J2EE container so that's why I've been digging into the spec to see if I can figure this out.


Yeah, it's possible that I may have been one of those who posted that information here in the past. (That there may be more than one instance of a servlet, that is.) It appears to be incorrect for Servlet 2.4, based on what you posted. Although I vaguely remember people posting that if there were several servlet mappings which referred to the same servlet, then the container could create an instance of the servlet for each servlet mapping. (This also may be incorrect as your quote from the spec doesn't mention or refer to that in any way.)

But anyway if you have to synchronize, I don't see that it makes much difference whether there's only one instance or not. Sure, if you're guaranteed there's only one instance you can synchronize on that instance, but if you aren't guaranteed that then you can synchronize on the servlet's class instead. And if you're uncertain about the number of instances you could plan for the worst and assume there might be more than one. There really isn't any significant difference between the two choices anyway.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
Well the SingleThreadModel is deprecated so I'm not going to use that. It is heavily recommended not to synchronize on one of the service methods so I was planning on synchronizing another method called from within doPost. But what you're suggesting is to just declare the entire class as synchronized?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61095
    
  66

Why does it need to be synchronized in the first place?


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
It's updating several database tables.
Bala Challa
Greenhorn

Joined: Feb 29, 2012
Posts: 1
Rob Micah wrote:It's updating several database tables.


Why don't you code a helper class and make a call from your Servlet?
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1012
    
    5

It's updating several database tables.


Shouldnt this logic be wrapped in a database transaction rather than making something synchronized?
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
The actual logic itself is in an EJB which calls a stored procedure on the database. But how would wrapping it in a transaction prevent duplicate inserts?
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1012
    
    5

Rob

What do you mean by duplicate?
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61095
    
  66

Yeah I'm still questioning why any synchronization is needed at all.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Rob Micah wrote:But what you're suggesting is to just declare the entire class as synchronized?


I don't know where you got that idea from. I said to use the class as the object to synchronize on. Let me spell it out in code of one syllable:
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
James Boswell wrote:Rob

What do you mean by duplicate?

This is difficult to explain without getting very deep into the logic of the entire web application. So I'm just going to try and describe it simply.

This particular servlet receives a request from the client and uses the information from that request to update several tables on a database. Sometimes that request from the client gets duplicated and I receive more than one request containing the same information. As long as the logic that does the update is synchronized this is not a problem. But right now it's not and so I'm looking for a way to do this.

Does that make sense?
Ram Narayan.M
Ranch Hand

Joined: Jul 11, 2010
Posts: 247

Since EJBs are thread safe... why need synchronization?


SCJP 6 [SCJP - Old is Gold]
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61095
    
  66

Yup, still not seeing any need to synchronize. Even without EJBs, database transactions should handle everything correctly.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
They are thread-safe but do they run more than one thread at a time? If so that doesn't solve my problem. The other problem I have is that this stored procedure I am calling from my EJB has a commit statement right in the middle of it.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Rob Micah wrote:The other problem I have is that this stored procedure I am calling from my EJB has a commit statement right in the middle of it.


Yup, that sounds like the culprit all right.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
Paul Clapham wrote:
Rob Micah wrote:The other problem I have is that this stored procedure I am calling from my EJB has a commit statement right in the middle of it.


Yup, that sounds like the culprit all right.

I really hope you are right but something's bothering me about this. If EJBs are thread-safe, shouldn't this method complete all the inserts/updates regardless of the extra commit before another execution of this EJB is allowed?
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

You seem to be interpreting "thread-safe" to mean that execution of the EJB's code by two separate threads at the same time can't happen. That is not the case. It means that since the EJB has no state, then execution of the EJB by two threads at the same time cannot update its state in inconsistent ways. It's certainly possible to do non-thread-safe things from an EJB -- "thread-safe" isn't like an attribute which is stamped into the code and inherited by everything the code touches -- and if your stored procedure is broken into two separate transactions, then it isn't thread-safe.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
Ok, but even after I remove the extra commit how does that keep me from having to synchronize its call? I still have the problem of duplicate requests that need to run one at a time.
James Boswell
Bartender

Joined: Nov 09, 2011
Posts: 1012
    
    5

Rob

Would it not be better for an additional piece of logic to check for and prevent duplicates?

I don't really see how using synchronized is going to help you here. Say you have 2 users, each with same request, trying to insert data into DB. Using synchronized is only going to prevent the inserts occurring together as opposed to one after the other. The end result will still be the same though - 2 duplicate records in DB.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
I do have a method for checking duplicate data. The problem is it's running concurrently and so a race condition occurs. As long as the duplicate request comes in after the original request is processed the duplicated request is properly rejected. How could I handle this without synchronizing on something?
Nauman Hasan
Ranch Hand

Joined: Jul 27, 2005
Posts: 34
You can use the the solution for the double submit pattern to solve this.

Double submit pattern

Regards,
Nauman
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18541
    
    8

Rob Micah wrote:I do have a method for checking duplicate data. The problem is it's running concurrently and so a race condition occurs.
Yes, that can easily happen if the duplicate-detection isn't part of the transaction which updates the database.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
Well, for this particular situation I can't use that solution because the duplication isn't happening on my server. But I think I may have found the best solution to this problem. The last step in the stored procedure I'm calling from my EJB inserts into a receipt table. By moving this insert to the beginning of the stored procedure and creating a primary key on the table it creates a blocking table-row lock. I've still got to test this but I think it will work.
Rob Micah
Ranch Hand

Joined: Aug 30, 2011
Posts: 94
Paul Clapham wrote:
Rob Micah wrote:I do have a method for checking duplicate data. The problem is it's running concurrently and so a race condition occurs.
Yes, that can easily happen if the duplicate-detection isn't part of the transaction which updates the database.

Paul, can you go into more detail here? When you say the duplicate detection isn't part of the transaction, do you mean part of the JDBC transaction?
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: Synchronizing on a static method