I'm very new to J2EE, so apologies if this is obvious. I have to work around a bad database design, which has an update which cannot be done safely in parallel. The easiest way to fix this (for now) is to place a mutex protection around the method call to serialize it's access.
I understand that you can't safely just use the synchronised keyword on the method in J2EE as the container may interfere. Is there a "supported" way in J2EE to make a mutex/semaphore/lock in an EJB to ensure access to a method is serialised for the entire J2EE application?
Try using a static object as the mutex, for example:
private static final Object mutex = new Object ();
public void someMethod() {
synchronized(mutex) {
// do work that must be globally synchronous
}
}
The reason that using synchronized on the method itself won't work for you is that the Java EE container may create multiple instances of EJBs but the methods marked synchronized are only protected on a per-instance basis (where each instance can have only one thread executing a synchronized method at a time, but multiple instances can be accessed concurrently).
Just for prosperity, the java.util.concurrent are all approved for use within the container. Blocking using a Semaphore will work within a single container, but you will need a higher level of synchronisation to maintain synchronisation in a cluster.
Related
Recently, I was asked in interview why wait, notify, and notifyAll are used. I explained them.
After that they asked me to assume an application is always single threaded. Is it really required? My answer was no.
Then, they asked why is design like wait, notify, and notifyAll are methods on the Object class. Why doesn't Java have an interface and these methods are in that interface and which ever class wants to implement it can use it. So, I was kind of stuck and unable to think over this design. Can anyone please sow light over this?
JVM uses OS-level threads. That means that each concrete JVM for each concrete OS handles threads differently. And these methods are not only implemented in Object class, they are marked as native, which kind of means that the are implemented in system layer of JVM.
And if those methods were in some interface, that would mean that anybody can redefine them.
Wait and notify and notifyAll is not just normal methods or synchronization utility, more than that they are communication mechanism between two threads in Java. And Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized. Remember synchronized and wait notify are two different area and don’t confuse that they are same or related. Synchronized is to provide mutual exclusion and ensuring thread safety of Java class like race condition while wait and notify are communication mechanism between two thread.
Then, they asked why is design like wait, notify, and notifyAll are methods on the Object class. Why doesn't Java have an interface and these methods are in that interface and which ever class wants to implement it can use it.
All of these methods are implemented in native code and they integrate closely with the synchronized block that wraps them. They are part of the Java language definition and have specific behaviors that programmers rely on. It would not be appropriate for them just to be interface methods that any object would implement.
When one object calls obj.wait(); on another object, it doesn't have to worry about the implementation of wait. It needs to make sure that it has a mutex lock on that object so it can make critical updates to it or other storage and if the wait method was implemented by the object itself, then that object could violate the language requirements and, for example, allow multiple threads into the protected block at the same time. A thread can synchronize and call wait/notify/notifyAll on another object or not without having to worry about whether or not that object has implemented those methods appropriately. By making them final methods on Object the behavior will work the same regardless of the object type or local implementation.
Also, as I mentioned, wait/notify/notifyAll are integrated closely with the surrounding synchronized block. When a thread is blocked in wait() the surrounding synchronized lock is released so that other threads can get access to the protected block. This coordination would not be possible if the wait() was just a simple method call without other strange language features.
This reminds me of my other answer here: Concept behind putting wait(),notify() methods in Object class
It was a design goal from the start that Java programs would be multithreaded. Remember the plan was for Java to make embedded programming less intimidating, the whole serverside web application thing (leading to the commoditization of Sun's core business) was an accident.
Since the goal was to enable creating embedded applications that would talk to other devices, it had to be multithreaded in order to be network-friendly and event-driven. But writing efficient multithreaded servers wasn't high on the list for java.
Java didn't have ReentrantLock or nonblocking i/o for a long time. Initially the main data structures available were Vector, Hashtable, and StringBuffer (all of which had synchronized on all public methods). From that choice it seems like the goal was good-enough, as opposed to being as efficient as possible. Later on it was clear Java needed to be more efficient for the use case of server applications and 1.2 introduced equivalents of Vector and Hashtable that were unsynchronized. This seemed like an afterthought, a course adjustment made once it was apparent Java had a new role it wasn't previously designed for.
If Java had stayed in the niche it was created for then possibly intrinsic locks might have been adequate. It seems the initial plan was for intrinsic locks only, so that the lock might as well be wired into the Object.
I need to access an API using their SDK.
Access (well, anything I need to access) requires the use of a context object. The same one.
Context context;
It is running with the possiblity (well, certainty) that multiple threads will access this same context object to perform various operations (via the 'context' object)
So, is all that is needed for Thread-Safety is to refer to it only via a synchronized getter()?
Example:
getContext().someOperation()
getContext().anotherOperation()
Definition:
public synchronized Context getContext() { return context; }
No, synchronizing only on the getter is not an option. There are two possibilities:
the Context object is threadsafe, in which case you don't need to synchronize on anything at all.
the Context object isn't threadsafe, in which case both your getter and anything else that touches it all have to synchronize on the same lock.
You should read up on the API and see whether the object is in fact threadsafe, usually with APIs that require sharing something like this it's only good sense from the API provider's point of view to protect it from concurrent changes.
Assuming the documentation is inadequate, which is typical, reasoning about the spec from the implementer's point of view can be useful. In this case, if the API requires synchronization, what would be the lock that you would synchronize on? For synchronization to work you need a shared lock. Usually the container is a lot better positioned to handle this kind of concern than you are on the client-side.
The synchronized keyword is pointing to the scope of the method. So only that method is thread-safe.
I.e., only that method can be called by one thread at a time (per instance, of course since the method is an instance method).
To make the context thread-safe, any actions on it need to occur within a synchronized block or method (unless the actions of the Context object are already thread-safe, of course).
I have a class "A" with method "calculate()". Class A is of type singleton(Scope=Singleton).
public class A{
public void calculate(){
//perform some calculation and update DB
}
}
Now, I have a program that creates 20 thread. All threads need to access the method "calculate()".
I have multicore system. So I want the parallel processing of the threads.
In the above scenario, can i get performance? Can all threads access the method calculate at same instance of time?
Or, Since the class A is singleton so, the threads needs to be blocked waiting.
I have found similar questions in the web/Stackoverflow. But I cannot get clear answer.
Would you please help me?
Statements like "singletons need synchronization" or "singletons don't need synchronization" are overly simplistic, I'm afraid. No conclusions can be drawn only from the fact that you're dealing with the singleton pattern.
What really matters for purposes of multithreading is what is shared. If there are data that are shared by all threads performing the calculation, then you will probably need to synchronize that access. If there are critical sections of code than cannot run simultaneously between threads, then you will need to synchronize that.
The good news is that often times it will not be necessary to synchronize everything in the entire calculation. You might gain significant performance improvements from your multi-core system despite needing to synchronize part of the operation.
The bad news is that these things are very complex. Sorry. One possible reference:
http://www.amazon.com/Java-Concurrency-Practice-Brian-Goetz/dp/0321349601/ref=sr_1_1?ie=UTF8&qid=1370838949&sr=8-1&keywords=java+concurrency+in+practice
That's the fundamental concept of Singleton. Only one instance of the class would be present in the system (JVM). Now, it depends on the implementation of calculate(). Is it a stateless utility method? If yes, you might not want to make it synchronized. In that case, multiple threads will be able to access it at the same instance of time. If calculate() is NOT stateless, i.e. it uses instance variables (and those instance variables will be used by multiple threads), then be careful; You have to make calculate() thread safe. You have to synchronize the method. At least you have to use a synchronize block inside the method. But, once you do so, only one thread will be able to access it (the synchronized block or the synchronized block inside the method) at any point of time.
public void calculate() {
//Some code goes here which does not need require thread safety.
synchronized(someObj) {
//Some code goes here which requires thread safety.
}
//Some code goes here which does not need require thread safety.
}
If you want to use parallel processing (if that's the primary goal), then singleton is not the design pattern that you should use.
I have found similar questions in the web/Stackoverflow. But I cannot get clear answer.
There is a good reason for that!!
It is not possible to say whether a method on a singleton does, or does not, need to be synchronized by virtue of being singleton.
Synchronization and the need for synchronization is all about state that may be shared by different threads.
If different threads share state (even serially), then synchronization is required.
If not then no synchronization is required.
The only clues that you have provided us that would help us give you a yes / no answer are this enigmatic comment:
// perform some calculation and update DB
... and the fact that the calculate() method takes no arguments.
If we infer that the calculate() method gets its input from the state of the singleton itself, then at least the part of the method (or the methods it calls) must synchronize while retrieving that state. However, that doesn't mean that the entire method call must be synchronized. The proportion of its time that the calculate method needs to hold a lock on the shared data will determine how much parallelism you can actually get ...
The updating of the database will also require some kind of synchronization. However, this should be taken care of by the JDBC connection object and the objects you get from it ... provided that you obey the rules and don't try to share a connection between multiple threads. (The database update will also present a concurrency bottleneck ... assuming that the updates apply to the same database table or tables.)
It depends on how you implement Singleton. If you use Synchronized keyword then they will wait else not.
Use Singleton with eager initialization.
Something like this:
public final class Universe {
public static Universe getInstance() {
return fINSTANCE;
}
// PRIVATE //
/**
* Single instance created upon class loading.
*/
private static final Universe fINSTANCE = new Universe();
/**
* Private constructor prevents construction outside this class.
*/
private Universe() {
//..elided
}
}
Above will perform very well in multithreaded environment. or else you can go for enum implementation of Singleton.
Check this link for various singleton implementation: http://javarevisited.blogspot.in/2012/07/why-enum-singleton-are-better-in-java.html
Multiple threads can invoke calculate() at the same time.
Those invocations won't be queued (executed serially) within that JVM unless you perform some type of concurrency control (making the method synchronized is one option).
The fact that your object is a singleton may or may not affect performance, depending on how that object's attributes (if any) are used within calculate().
Also bear in mind that since you are "updating DB", table or row level locks may also limit concurrency.
If you are worried about performance, the best bet is to test it.
If there is a servlet, inside a servlet container such as Websphere. The servlet are executed by some threads. I would like to ask, what does the threads share? How variables are shared between them?
Do they have a local copy of the following variables?
1) private/protected/public final Semaphore permits = new Semaphore(50);
2) private/protected/public final static Semaphore permits = new Semaphore(50);
3) private/protected/public Semaphore permits = new Semaphore(50);
4) private/protected/public static Semaphore permits = new Semaphore(50);
How should I declare the semaphore so that I can use semaphore to control them? I don't want them to have each of them a copy of the semaphore. Thanks.
Threads are run by Websphere thread pool and you should not be concerned about accessing them or sharing information via them.
Your semaphore will be shared if you declare it static in your servlet, for as long as all classes that use it live in the same application under the same classloader. However, there is a big risk in this case that if your execution path does not release permit (for example due to exception) you may end up with all threads blocked.
Each thread has its own stack, but all share the same memory space. With that in mind, a single instance can be shared, and so its state/properties, among multiple threads. Hence, we need to take care of state using synchronisation or similar techniques.
If you define a static variable or a single instance of servlet will be used -- which is highly likely but no guarantee, then it would be the same for all threads.
Nonetheless, you should create a class which provide a singleton semaphore to be used in servlet. That way servlet instances will be using the one and the same semaphore object, no matter what.
If you want to share a semaphore, it must be created by one thread, then handed out to the others (via some form of (possibly static) getter method) when they need it.
If you create the Semaphore object in each object, they'll all have different ones, defeating the purpose.
Servlets must be thread safe. This means your servlets should be "stateless" (unless you really know what you're doing). Essentially, use only local variables - not fields.
If you want to share state, by all means use fields of your servlet, or use classes with static fields and static getters (like the singleton pattern)
Servlets should be threadsafe. Meaning if they have any state, they should be synchronized. Try avoiding saving some state inside servlets. They should contain only business/controller logic. Any state you want to save, put them in servletcontext/request/session which are synchronized by the container.
Each servlet is executed in a new thread.. Technically, there is worker threads that waits for requests, when a http request comes to servlet container, this one instantiates a new servlet (depending to servlets defined in web.xml) and passes it to the worker thread. So logically each variable is not seen by other servlet instances. Now if you want to make your variable visible by all servlet instances you have to define it as static so it will be shared between all instances of the same class.
You should not count on two instances of a servlet even being in the same JVM. Containers can be replicated and your Servlets need to be stateless. Besides the Java EE spec does not allow you to do any threading manipulation within. The containers may allow it, but the behaviour then becomes implementation specific. By putting semaphores in there you are interfering with the pooling and can cause issues. Use Sessions if you need to differentiate between different users.
I actually have two questions about Java RMI and thread synchronization:
1) If I implement my RMI remote methods as synchronized, are they guaranteed to be mutually exclusive? I need to make sure that no two of my RMI methods (methods offered to clients) execute at the same time.
2) I have a method that the server executes periodically. It is used to do cleanups. I have to make sure that this particular method does not execute when there is any RMI method being run/used by remote clients. Also, when that method is running, RMI calls shouldn't be possible. I.e. Clients must wait. Any idea how I can do that? I have read about Locks, but I do not know how to use them in this scenario.
I have considered implementing RMI methods as static and including that cleanup method inside the RMI interface, but it does not seem to be an elegant way of solving the problem.
I have also written the cleanup method inside the RMI interface as synchronized. When I ran it for testing, there did not seem to be collisions between methods, but I cannot be sure.
Thank you for your time and answers.
1) If I implement my RMI remote
methods as synchronized, are they
guaranteed to be mutually exclusive? I
need to make sure that no two of my
RMI methods (methods offered to
clients) execute at the same time.
RMI does not provide such guarantee on its own (unlike EJB) and two calls on the same remote object may be executed concurrently unless you implement some synchronization. Your approach is correct, and synchronizing all methods will indeed ensure that no two of them run at the same time on the same object. Note: The keyword synchronized alone is equivalent to synchronized( this ).
2) I have a method that the server
executes periodically. It is used to
do cleanups. I have to make sure that
this particular method does not
execute when there is any RMI method
being run/used by remote clients.
If the cleanup job is in another class, you will need to define a lock that you will share between the remote object and the cleanup job. In the remote object, define an instance variable that you will use as a lock.
protected Object lock = new Object();
By convention, people use an Object for this purpose. Then you need to grab the lock in your periodic job with synchronized( remoteObj.lock ) { ... }, assuming it's in the same package.
The other methods in the remote object will need to be synchronized the same way (synchronized alone is not enough), so that remote method calls and periodic job are both exclusive.
I have considered implementing RMI
methods as static and including that
cleanup method inside the RMI
interface, but it does not seem to be
an elegant way of solving the problem.
I have also written the cleanup method
inside the RMI interface as
synchronized. When I ran it for
testing, there did not seem to be
collisions between methods, but I
cannot be sure.
If I understand well, you would like to have the cleanup logic be a static method? A static method with synchronized alone grabs a lock on the class. A "regular" method with synchronized grabs a lock on the object instance. These are not the same implicit locks!
But if you have only one remote object instantiated, you can make the lock static (That's the same as locking on the class, but is a bit cleaner). The cleanup code can then be static as well and be in the same class as the remote object or not.
Skeleton:
public class MyRemoteClass {
public static Object lock = new Object();
public void doStuff()
{
synchronized( lock ) { ... }
}
}
public class Cleanup {
public static void doIt()
{
synchronized( MyRemoteClass.lock ) { ... }
}
}
For each call from a RMI client the RMI server will execute the call in a new thread. You only need to synchronize access to shared objects.
Another thread or timer will not stop your server from accepting calls from the client side. This needs synchronization, the best practice depends on how long the cleanup job runs can it be interrupted, or would it be possible to put the requests in a queue etc.
The easiest way would be to let the RMI methods wait for the lock as already described by ewernli.
EDIT: According to your comment, a skeleton that demonstrates how to achieve this kind of basic synchronization. Since everything is now mutually exclusive, you can't expect high performance with multiple clients involved. Anyway this would cover your requirements. (I hope). If your project grows you should read the Concurrency Tutorial
Object mutex = new Object();
int rmiMethod1() {
synchronized (mutex) {
doWhatNeeded1();
}
}
int rmiMethod2() {
synchronized (mutex) {
doWhatNeeded2();
}
}
// in your cleanup thread
void run() {
synchronized (mutex) {
cleanUp();
}
}
To clarify all this confusion:
If you synchronize your remote method implementations only one client can be executing at a time.
If you synchronize your cleaner task on the remote object it joins (1).
You can't define remote methods as static.
You must keep in mind that RMI creates the illusion of a "remote object", but in reality there are no less than three objects: the local stub, the remote skeleton and the actual remote object. As a design trade-off this illusion is not complete and is locking only the local stub. There is no synchronization across the network. Search the internet for RMI+stub+synchronized and you will find plenty of explanations, like for instance this one:
Java RMI and synchronized methods
So you need to implement some kind of non-RMI, purely server-side synchronization yourself. Then you can invoke this pure server-side locks from your remote methods; but you need the additional level of indirection.
To test your code the easiest is to pause your threads under a good debugger like Eclipse. Eclipse will clearly show you which paused thread is holding which lock blocking which other thread(s).