views:

1327

answers:

5

If I declare a singleton servlet like

public static class SomeServlet extends HttpServlet {.....

It gives the error indicating that modifier static not allowed here in NetBeans.

Please let me know how to create a singleton servlet which allows only one client at a time to execute.

Thanks in Advance, Mahes

+5  A: 
  • static has nothing to do with being executed by only one thread at any point in time.
  • you can have static classes as inner classes, but this doesn't help your problem due to the first point
  • If I recall correctly there's only one servlet instantiated ever, so there's no need to create singletons. Update: I didn't remember correctly as DefLog pointed out
  • therefor synchronize on a method (doGet, doPost, service or your implementation method) update: will not do the trick.

Based on your demonstrated understanding of the problem (no pun intended) I doubt that this is the solution you should be choosing. Rather rephrase your question so that you state the problem you're trying to solve with the solution you have stated in your first revision of the question.

Update: See the comments to this answer for why you really don't want to fall for synchronized. You might (for example) want to have multiple servlets accessing the same functionality one at a time. Plus you'd introduce severe scaling problems if you synchronize on a servlet level. It's definitely the wrong place for solving concurrency problems.

Olaf
synchronize on a method may not necessarily work, although it might make you think that it does.
Tom Hawtin - tackline
right - that's why I added the last paragraph. I doubt that the answer helps solving the root problem. It's rather a reaction to the stated suggested solution.
Olaf
(note: my previous comment was a reaction to Tom)
Olaf
It is incorrect that only one instance of a servlet is instantiated by the container. The specification does not demand it even if most containers implement it as such. More heavy weight containers allocate a number of threads to an instance and instantiate more if there are more requests.
DefLog
thanks for clarification. I'll add this information to the answer...
Olaf
Nice updates. :)
Tom Hawtin - tackline
@DefLog: servlet specification says that container should instantiate only one servlet instance per declaration (unless servlet implements SingleThreadModel interface).
Peter Štibraný
"If I recall correctly there's only one servlet instantiated ever" ... you are right (usually). See http://stackoverflow.com/questions/1228424/configuring-tomcat-to-only-raise-one-servlet-per-application/1228599#1228599
Peter Štibraný
+1  A: 

Implement SingleThreadModel. But note that: it's deprecated, it may not do anything/make sense, it's a daft thing to do (much like singletons).

Tom Hawtin - tackline
+2  A: 

I really strongly oppose the idea of making a Servlet that can only handle one request at a time. You should probably make another (properly synchronized class) and have your servlet putting requests in some sort of execution queue.

Slartibartfast
A: 

A top-level declaration can never be static. static means that an element is declared on the class level, so it needs an enclosing class declaration.

With servlets there will be usually one but possibly more instances of that servlet which handle requests concurrently. So, maybe you don't really want to reduce concurrency at this level, or you would use servlet filters or a framework like Spring Security that can limit the number of concurrent sessions.

eljenso
A: 

I tend to think that Singletons are overused, and often indicate a flaw with the basic architecture of a solution. Assuming you've done enough analysis to prove you need a Singleton, you can use an older Singleton pattern that doesn't rely on static initialization. Here's an example:

public SomeServlet extends HttpServlet {

    private instance = null;

    private SomeServlet() {
        // Construction code here
    }

    public synchronized SomeServlet getInstance() {
        if(instance == null) {
            instance = SomeServlet();
        }
        return instance;
    }

    // Servlet methods here

}

I see two potential problems though:

First, you'll need a wrapper Servlet (or maybe just chain from another servlet, since the Servlet container won't know how to deal with not having a private constructor.

Second, you'll still need to synchronize the servlet methods because you still can't guarantee that there's only one executor thread "in" the servlet at a time.

Steve Moyer
You might want to Google "double checked locking is broken java 6". It found this: http://www.ibm.com/developerworks/java/library/j-dcl.html
duffymo
Great article ... nasty ramifications for Java 6. I've almost completely eliminated the Singleton pattern from my code, but I'll be sure to remember that for future upgrades.
Steve Moyer
That code is really confused.
Tom Hawtin - tackline