I am relatively new to Scala and functional programming, and I like the idea that using immutable objects can avoid many of the problems associated with threads. I'm still haunted, and this is a classic example used to teach thread safety - a common counter.
I was wondering if it is possible to implement a thread-safe counter (request counter in this example), use immutable objects and functional concepts, and completely eliminate synchronization.
So, for reference, here are first the classic mutable counter versions (excuse me for the public member variable, just for brevity examples)
Mutable, Non thread safe version:
public class Servlet extends HttpServlet { public int requestCount = 0; @Override public void service(ServletRequest req, ServletResponse res) throws ... { requestCount++;
Mutable, classic version with streaming security: (or I hope ...)
public class Servlet extends HttpServlet { public volatile int requestCount = 0; @Override public void service(ServletRequest req, ServletResponse res) throws ... { synchronized (this) { requestCount++; } super.service(req, res); } }
I was wondering if there is a way to use immutable objects and variable variables to ensure thread safety without synchronization.
So here is my naive attempt. The idea is to have an immutable object for the counter and simply replace the reference to it using a mutable variable. Feels fishy, but worth a shot.
Owner:
public class Incrementer { private final int value; public Incrementer(final int oldValue) { this.value = oldValue + 1; } public Incrementer() { this.value = 0; } public int getValue() { return value; } }
Modified Servlet:
public class Servlet extends HttpServlet { public volatile Incrementer incrementer = new Incrementer(); @Override public void service(ServletRequest req, ServletResponse res) throws ... { incrementer = new Incrementer(incrementer.getValue()); super.service(req, res); } }
I have a strong feeling that this is also not thread safe, since I am reading with an increment and can get an obsolete value (for example, if the link has already been replaced by another thread). If this is really not thread safe, then I wonder if there is any “functional” way to handle such a counter script without locking / synchronizing.
So my question (s)
- How safe is this thread?
- If so, why?
- If not, is there any way to implement such a counter without synchronization?
Although the above sample code is provided in Java, answers in Scala are of course also welcome.