Is synchronisation needed here? - java

I have a a servlet called Statelessservlet which instantiates a new stafeful object every time. Do I need to provide synchronisation to this stateful object?
Here's the code:
public class StatelessServlet extends HttpServlet {
#Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
StatefulObject stObj = new StatefulObject(Integer.parseInt(req.getParameter("id")));
stObj.performSomeStatefulOperation();
...
}
}
class StatefulObject {
private int id;
public StatefulObject(int id) {
this.id = id;
}
//Is synchronized really needed here???
public synchronized void performSomeStatefulOperation() {
id++;
}
}
As per Brian Grotz JCIP each stafeful object should be synchronised, so Ideally we should synchronise this method?

If each interaction with your server creates a new object and discards it, then it's relatively safe not to have synchronization (there is no shared state between multiple threads accessing the service at the same time).
If, on the other hand, those objects are reused, you must synchronize that method.
Also, if, for instance, your performSomeStatefulOperation changes state of some shared data, then you should synchronize it, unless you took other steps to guarantee it's thread safety (using locks, for instance).
To sum up, it depends on what you're doing in your method. From what you show, there is no need, if there could be a problem from multiple invocations of that method (because it updates shared state), then you should synchronize it.

No synchronization needed since each thread gets its own instance of StatefulObject which is unreachable to other threads.

Related

Concurrency handling correct?

Proxy will be called from multiple thread, and Proxy.setWorker() may be called at some time, does anyone know if below implementation will cause problem?
class Worker {
void methodA() {
...
}
void methodB() {
...
}
};
… and …
class Proxy {
volatile Worker mWorker;
final boolean cond= true;
public void setWorker(Worker worker) {
mWorker = worker;
}
void methodA() {
if(cond)
mWorker.methodA();
}
void methodB() {
if(cond)
mWorker.methodB();
}
}
You get a data race when there are 2 threads doing a read/write or write/write to the same field and these reads/writes are not ordered by the happens-before relation (so there is no happens-before edge between them).
The 'worker' field is volatile, so there is a happens-before edge due to the volatile variable rule; hence, there is no data-race.
I would make the 'cond' field final if possible to prevent confusion. If you would modify the 'cond' field, then your code could have a data-race unless you make it volatile.
It depends on if you have a separate Proxy for each thread. If you do you are fine. If you don't and you try and call setWorker from two places at the same or if you try and one of the methods while setting the worker or if either of the methods modify proxy or worker you will have some data race issues.

How can I synchronize the class so that I can use from UI thread and background threads?

I have a utility class as follows:
public class MetaUtility {
private static final SparseArray<MetaInfo> metaInfo = new SparseArray<>();
public static void flush() {
metaInfo.clear();
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
metaInfo.append(key, info);
}
public static MetaInfo getMeta(int key) {
return metaInfo.get(key);
}
}
This class is very simple and I wanted to have a "central" container to be used across classes/activities.
The issue is threading.
Right now it is populated (i.e the addMeta is called) only in 1 place in the code (not in the UI thread) and that is not going to change.
The getter is accessed by UI thread and in some cases by background threads.
Carefully reviewing the code I don't think that I would end up with the case that the background thread would add elements to the sparse array while some other thread would try to access it.
But this is very tricky for someone to know unless he knew the code very well.
My question is, how could I design my class so that I can safely use it from all threads including UI thread?
I can't just add a synchronized or make it block because that would block the UI thread. What can I do?
You should just synchronize on your object, because what your class is right now is just a wrapper class around a SparseArray. If there are thread level blocking issues, they would be from misuse of this object (well, I guess class considering it only exposes public static methods) in some other part of your project.
First shoot can be with synchronized.
#Jim What about the thread scheduling latency?
Android scheduler is based on Linux and it is known as a completely fair scheduler (CFS). It is "fair" in the sense that it tries to balance the execution of tasks not only based on the priority of the thread but also by tracking the amount of execution time that has been given to a thread.
If you'll see "Skipped xx frames! The application may be doing too much work on its main thread", then need some optimisations.
If you have uncontended lock you should not be afraid of using synchronized. In this case lock should be thin, which means that it would not pass blocked thread to OS scheduler, but would try to acquire lock again a few instructions after. But if you still would want to write non-blocking implementation, then you could use AtomicReference for holding the SparseArray<MetaInfo> array and update it with CAS.
The code might be smth like this:
static AtomicReference<SparseArray<MetaInfo>> atomicReference = new AtomicReference<>();
public static void flush() {
atomicReference.set(new SparseArray<MetaInfo>);
}
public static void addMeta(int key, MetaInfo info) {
if(info == null) {
throw new NullPointerException();
}
do {
SparseArray<MetaInfo> current = atomicReference.get();
SparseArray<MetaInfo> newArray = new SparseArray<MetaInfo>(current);
// plus add a new info
} while (!atomicReference.compareAndSet(current, newArray));
}
public static MetaInfo getMeta(int key) {
return atomicReference.get().get(key);
}

Fine-grained synchronization/locking of method calls based on method parameters

I want to synchronize method calls on basis some id i.e. something like a concurrency Decorator of a given object instance.
For example:
All threads which call the method with param "id1", should execute serially to one another.
All of the rest, which call the method with different argument, say "id2", should execute in parallel to the threads which call the method with param "id1", but again serially to each other.
So in my mind this can be implemented by having a lock (http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/locks/ReentrantLock.html) instance per such method param.
Each time the method is called with the param, the lock instance corresponding to the specific param value (e.g. "id1") would be looked up and the current thread would try to obtain the lock.
Speaking in code:
public class ConcurrentPolicyWrapperImpl implements Foo {
private Foo delegate;
/**
* Holds the monitor objects used for synchronization.
*/
private Map<String, Lock> concurrentPolicyMap = Collections.synchronizedMap(new HashMap<String, Lock>());
/**
* Here we decorate the call to the wrapped instance with a synchronization policy.
*/
#Override
public Object callFooDelegateMethod (String id) {
Lock lock = getLock(id);
lock.lock();
try {
return delegate.delegateMethod(id);
} finally {
lock.unlock();
}
}
protected Lock getLock(String id) {
Lock lock = concurrentPolicyMap.get(id);
if (lock == null) {
lock = createLock();
concurrentPolicyMap.put(id, lock);
}
return lock;
}
}
protected Lock createLock() {
return new ReentrantLock();
}
It seems that this works - I did some performance testing with jmeter and so on.
Still, as we all know concurrency in Java is a tricky thing, I decided to ask for your opinion here.
I can't stop thinking that there could be a better way to accomplish this. For example by using one of the BlockingQueue implementations. What do you think?
I also can't really decide for sure if there is a potential synchronization problem with getting the lock i.e. the protected Lock getLock(String id) method. I am using a synchronized collection, but is that enough? I.e. shouldn't it be something like the following instead of what I currently have:
protected Lock getLock(String id) {
synchronized(concurrentPolicyMap) {
Lock lock = concurrentPolicyMap.get(id);
if (lock == null) {
lock = createLock();
concurrentPolicyMap.put(id, lock);
}
return lock;
}
}
So what do you guys think?
Lock creation issues aside, the pattern is OK except that you may have an unbounded number of locks. Generally people avoid this by creating/using a Striped lock. There is a good/simple implementation in the guava library.
Application area of lock-striping
How to acquire a lock by a key
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/Striped.html
Example code using guava implementation:
private Striped<Lock> STRIPPED_LOCK = Striped.lock(64);
public static void doActualWork(int id) throws InterruptedException {
try {
STRIPPED_LOCK.get(id).lock();
...
} finally {
STRIPPED_LOCK.get(id).unlock();
}
}
Though I would personally prefer Guava's Striped<Lock> approach suggested by Keith, just for discussion & completeness, I'd like to point out that using a Dynamic Proxy, or the more generic AOP (Aspect Oriented Programming), is one approach.
So we would define an IStripedConcurrencyAware interface that would serve as the "something like a concurrency Decorator" that you desire, and the Dynamic Proxy / AOP method hijacking based on this interface would de-multiplex the method call into the appropriate Executor / Thread.
I personally dislike AOP (or most of Spring, for that matter) because it breaks the what-you-see-is-what-you-get simplicity of Core Java, but YMMV.

Fastest synchronization technique

Following is a rather common scenario of accessing a common resource, either in a sequential (single-threaded) or a concurrent (multi-threaded) way, for which the fastest technique is needed.
More specifically (see sample source code below), a Manager class creates some instances of a Runnable (or Callable) class (Handler) with a common resource (a Store object). The Manager class is actually subclassed and its execute() method overridden to run the handlers sequentially in the same thread, or in multiple threads (e.g., via an ExecutorService), depending on the subclass implementation.
My question is, what would be the fastest (less overhead) way of synchronizing access to the shared Store object inside the run (or call()) method of each Handler object, especially taking into account that, for single-threaded access, that synchronization is redundant (but has to be there, because there are also multi-threaded Manager subclass implementations).
Would, for instance, a synchronized (this.store) {this.store.process()} block be better than, say, using a Lock object from java.util.concurrent, before and after calling this.store.process()? Or would a separate synchronized method inside Handler for each store access be faster? For example, instead of calling this.store.process(), run something like
private synchronized void processStore()
{
this.store.process();
}
Following is the (sample) source code.
public class Manager
{
public Manager()
{
Store store = new Store(); // Resource to be shared
List<Handler> handlers = createHandlers(store, 10);
execute(handlers);
}
List<Handler> createHandlers(Store store, int count)
{
List<Handler> handlers = new ArrayList<Handler>();
for (int i=0; i<count; i++)
{
handlers.add(new Handler(store));
}
return handlers;
}
void execute(List<Handler> handlers)
{
// Run handlers, either sequentially or concurrently
}
}
public class Handler implements Runnable // or Callable
{
Store store; // Shared resource
public Handler(Store store)
{
this.store = store;
}
public void run() // Would be call(), if Callable
{
// ...
this.store.process(); // Synchronization needed
// ...
this.store.report(); // Synchronization needed
// ...
this.store.close(); // Synchronization needed
// ...
}
}
public class Store
{
void process() {}
void report() {}
void close() {}
}
In general: CAS synchronization < synchronized < Lock in terms of speed. Of course this will depend on the degree of contention and your operating system. I would suggest you try each and determine which is the fastest for your need.
Java also performs lock elision to avoid locking on objects that are only visible to one thread.
As my knowledge if your app run or will run at cluster mode then synchronized will not work ( different JVM) so Lock will be the only option.
If the common resource is queue then you can use ArrayBlockingQueue, if not then start synchronized access for this resource.

Static Variables Behaviour in a Java Servlet

I am developing a java servlet that while running, starts different objects methods in new threads. Those threads should access a variable that describes the specific servlet instance, say jobId. For this reason, i declared the jobId variable as static. The servlet constructor is calculating this value for each servlet instance (call).
I was wandering if the servlet is called few times at the same time, the static jobId variable is shared between the calls, which means that some threads will get the wrong jobId, or it is calculated once for each call- so the threads that a specific servlet started will use the jobId calculated for this specific servlet (which is the way i want it to work).
Any ideas?
Thanks a lot!
A servlet is created only once on webapp's startup and shared among all requests. Static or not, every class/instance variable is going to be shared among all requests/sessions. You would not like to assign request/session scoped data to them. Rather declare/assign them as methodlocal variable. E.g.
public class MyServlet extends HttpServlet {
private static Object thisIsNotThreadsafe;
private Object thisIsAlsoNotThreadsafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadsafe;
thisIsNotThreadsafe = request.getParameter("foo"); // BAD! Shared among all requests.
thisIsAlsoNotThreadsafe = request.getParameter("foo"); // BAD! Shared among all requests.
thisIsThreadsafe = request.getParameter("foo"); // Good.
}
}
There exist the legacy and deprecated SingleThreadModel interface which you can let your servlet implement to force creation during every request. But this is a bad design and unnecessarily expensive. That's also why it's deprecated.
See also:
Servlet instances and multithreading
How do servlets work?
static means that every instance will access to the same value.
So every user connected to the servlet will access to the same value. Your jobId will be probably wrong when 2 users or more are connected together.
You have to get your own value a each connection and store it somewhere else.
Resources :
static variable in servlet - when can we use?
On the same topic :
Sharing a static object between a servlet and a webservice
Static variables are shared. Static variables don't belong to any one instance, they are accessible by all instances of the class. When you are using a constructor, that is used to create one object (one instance of the class), setting a static variable in a constructor typically doesn't make sense because it's something that is outside the scope of the object you're creating.
As for what would work, you could put the jobId in the HttpSession and then each user would have their own copy of it.
The instantiation policy for servlets is not defined in the servlet spec (as far as I can remember, anywho) but the usual behavior seems to be to create only one instance per servlet configuration. So, in your case, every request would use the same variable.
If I were you, I'd consider to send the jobId as a parameter to the Runnables you're running the threads with. For example, in stead of this:
public class HelloWorld extends HttpServlet {
private static long jobId;
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
jobId = Long.parseLong(request.getParameter("jobid");
new Thread(new Worker()).start();
}
static class Worker implements Runnable {
#Override
public void run() {
doSomethingWith(jobId);
}
}
}
Refactor away the static variables like this:
public class HelloWorld extends HttpServlet {
// private static long jobId; -- delete, no longer needed
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long jobId = Long.parseLong(request.getParameter("jobid"); // local variable
new Thread(new Worker(jobId)).start(); // send jobId as parameter
}
static class Worker implements Runnable {
private final long jobId; // non-static; every instance has one
public Worker(long jobId) { // allow injection of jobId
this.jobId = jobId;
}
#Override
public void run() {
doSomethingWith(jobId); // use instance variable instead of static
}
}
}
Easier to read, no concurrency problems - pure win.

Categories