1

First thing I wan't to clarify is, I know Servlet is single instance multi-threaded model. Container maintains on instance and creates multiple threads per multiple requests to handle and all the threads work on same servlet instance. Also, we shouldn't maintain state in a servlet as it causes multi-threading/concurrency issues. Cool!! What if the state (member's of servlet) itself is thread-safe?? As in below example

public class MyCrazyServlet extends HttpServlet {
  StringBuffer s1 = new StringBuffer("stackoverflow");
  static StringBuffer s2 = new StringBuffer("stackexchange");
  public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    String s3 = "I'm safe";
    HttpSession crazySession = request.getSession();
    //more stuff here
  }
}

In above snippet, I presume except crazySession local variable (HttpSession instance) everything else (s1, s2 and s3) is thread safe

Please correct, if my understanding is wrong

Mureinik
  • 297,002
  • 52
  • 306
  • 350
JavaHopper
  • 5,567
  • 1
  • 19
  • 27
  • 1
    Yeah, `StringBuffer` is thread safe. Not to be confused with the very similar class `StringBuilder` which is not thread safe. – Dawood ibn Kareem Dec 25 '13 at 03:58
  • "A thread-safe, mutable sequence of characters." - http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html – Nayuki Dec 25 '13 at 04:04
  • So, @DavidWallace and Nayuki... s1, s2 and s3 are all thread safe right?? I'm confirming because my tutor is saying only s3 is thread safe – JavaHopper Dec 25 '13 at 04:23
  • `StringBuffer`s lock when you use them, so if two threads try to access them at the same time, one of them will have to wait. – Dawood ibn Kareem Dec 25 '13 at 04:24
  • StringBuffer guarantees that multiple concurrent calls on the object are done one by one, but nothing more. So what is your need? – Amir Pashazadeh Dec 25 '13 at 06:14

1 Answers1

3

In the given snippet, s2 is never modified, so it must be safe. But this isn't really the interesting usecase now, is it?

StringBuffer is thread safe in the sense that if two different threads modify it concurrently, one call will wait for the other to end, so that both call will be fully executed without messing each other up.

Consider the following code snippet:

// name is retrieved from the calling session
public void addName (String name) {
    // s2 is defined as:
    //    static StringBuffer s2 = new StringBuffer("stackexchange")
    // by the OP
    s2.append(name);
}

If both you (JavaHopper) and I (Mureinik) call this function concurrently, you are guaranteed that the content won't get scrambled. Depending on the exact timing of the calls and the context-switches, s2 will either contain "stackexchangeJavaHopperMureinik" or "stackexchangeMureinikJavaHopper".

But here's the pitfall - you need to be very, very careful with your calls. More often than not, you'd want to chain several calls, e.g.:

// name is retrieved from the calling session
public void addName (String name) {
    // s2 is defined as:
    //    static StringBuffer s2 = new StringBuffer("stackexchange")
    // by the OP
    s2.append("[").append(name).append("]");
}

In this example, each append is a different call. So the two concurrent calls described above may yield a valid result like "stackexchange[JavaHopper][Mureinik]", but may very well yield something like "stackexchange[JavaHopper[Mureinik]]".

To summarize: Be careful. Be very careful. Depending on how complicated your code is, it might be a better idea to handle synchronization on your own.

Mureinik
  • 297,002
  • 52
  • 306
  • 350