Abidi
Abidi

Reputation: 7996

Hit Counter Servlet

Race condition could occur even when "check-and-act" action is not involved, for example in the following code ten requests would result in ten threads but the counter is not guaranteed to be 10 after that. First of all am I right in saying that?

private int numPageHits;   
public void doGet(HttpServletRequest request, 
                                 HttpServletResponse response) 
                                       throws IOException, ServletException 
    { 
       //this method executes whenever the servlet is hit 
       //increment numPageHits 
       numPageHits++; 
    }

One solution could be to use synchronize block like:

synchronize(this) {
    numPageHits++; 
}

I was just wondering if there is another way of handling this situation?

Thanks

Upvotes: 0

Views: 1453

Answers (3)

Chris Fregly
Chris Fregly

Reputation: 1530

you are correct. ++ is not an atomic operation (even though it looks like it is) and therefore subject to reordering optimizations and thread context switches by the JVM/Java Memory Model.

++ is technically a 3 operation "get-and-set": 1) retrieve the current value 2) add 1 to the value 3) store the new value

thread context switches can occur anywhere in those 3 steps causing each thread to see diff values at any given point in time.

this is a perfect candidate for Atomics, as others have pointed out. here's a good link on this topic: http://www.javamex.com/tutorials/synchronization_concurrency_7_atomic_updaters.shtml

making the counter variable volatile is not enough here as the new value depends on the old and therefore subject to race conditions caused by the context switching. here's another good link: http://www.ibm.com/developerworks/java/library/j-jtp06197.html

this is a very common interview question, btw...

Upvotes: 0

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340723

As pajton suggested, use AtomicInteger or AtomicLong, incrementAndGet() method would be even better.

The code without synchronized is not only a subject of race condition, but also introduces thread visibility problem. See volatile keyword.

Upvotes: 1

pajton
pajton

Reputation: 16226

Use AtomicInteger and its method AtomicInteger.addAndGet()

Upvotes: 3

Related Questions