People tell about two types of multi-threaded locking - object and class. In my knowledge, locking is done on objects only.
Case 1: On objects we create using new or factory methods etc.
void synchronized myMethod(Type param) {
//will lock on the instance used to call this method
}
or
synchronized(this) {
//will lock on current object
}
or
synchronized(obj1) {
//will lock on specified obj1 object
}
Case 2: On java.lang.Class objects
This is called class lock, and can be used with static fields or methods or blocks, as they belong to class and shared among all the objects, and other class properties.
static void synchronized method() {
//will lock the Class object
}
or
static {
synchronized(SomeClass.class){
int a = 2;
}
}
Why I am thinking this also as an object locking because classes are loaded into the Method Area in the JVM, and all the static properties of the class are wrapped inside a java.lang.Class object created by JVM. So behind abstraction, its object locking and in the picture, we see Class locking.
So I can also infer one more thing. Just as objects locked by a thread can not be acquired by another thread as long as it is not released by first thread, class locking (the java.lang.Class instance) also works in same manner.
I want to know in case of synchronized static methods, lock on which class is acquired by the thread in following two cases:
This method is called from same class where it is defined.
This method is called from derived class with derived class name.
This is my understanding so far regarding the subject. Please add on or rectify.
People tell about two types of multi-threaded locking - object and class.
A Class is an Object. There is only one kind of locking in the Java language: Every Object (including every Class) has a mutex that can be locked by a synchronized block or a synchronized method. The Object to be locked is implicit in a synchronized method: It's the "this" instance for an instance method, and it's the Class object for a static method.
One of the most common newbie mistakes is to think that two different threads can't get into the same synchronized block at the same time. They can, and there's plenty of questions and answers here in StackOverflow that prove it. Another mistake is to think that if one thread is synchronized on some object, then other threads will not be able to modify the object. They can and they do.
Synchronization prevents two or more threads from synchronizing on the same Object at the same time. Which object is the right object? It's all about protecting your data. If the structure that you want to protect is a linked list, for example, then a good choice would be for any method that accesses the list to synchronize on the list header. If you want to protect global data (e.g., static variables), then you want to synchronize on a global object (e.g., the Class object that owns the variables.) The important thing is that, if you have read/write data (a.k.a., "mutable data") that are accessed by more than one thread, then every method that accesses the same data must synchronize on the same lock.
There is another kind of locking in Java, but it's not in the Java language; it's in the Java standard library. It's available through objects that implement the java.util.concurrent.locks.Lock interface. Of course a Lock object (like any Object) also implements the first kind of locking, but you should never, ever, synchronize on a Lock object unless you want to give people the impression that you are a clueless newbie.
The java.util.concurrent-style locking is more powerful than using synchronized blocks because of it's explicit lock() and unlock() methods. For example, it is possible for one method to lock a lock, and a different method to unlock it. That can lead to code that is tricky to understand, and I wouldn't do it unless I had a very good reason, but sometimes there are good reasons.
The only difference is that a static synchronized locks on the class instance and a non-static synchronized method locks on the instance.
People tell about two types of multi-threaded locking
There is object instance locks and Lock style locks. A Lock, confusingly, has both.
object and class
Not true as you have worked out already.
Just because people say stuff doesn't make it true. Often people say a lot of nonsense. In fact there is whole web sites devoted to non-sense about Java. :P
Related
This question already has answers here:
What is the difference between synchronized on lockObject and using this as the lock?
(5 answers)
Closed 4 years ago.
I am cleaning up a legacy java code and I found following construct:
final class QuiteComplexClass {
private Object lock = new Object();
void aMethod() {
...
synchronized(lock) {
....
}
}
}
Is the special object for locking necessary here? What is difference when I used simple synchronized (this)?
I think it might by useful when the class is publicly visible and somebody may call synchronized on the class instance by mistake. But this class is package private so no external code can do that.
The difference is that if you use this as lock or mark method as synchronized then another piece of code could accidentally (or intentionally) use your QuiteComplexClass object as a lock. And it might cause your code to work incorrectly. If some other developer decides to write the code as below then your code will not be able to call synchronized methods on qcc instance while lock is being held.
synchronized(qcc) { // assuming qcc is an instance of QuiteComplexClass
while (true); // or any other time consuming operation
}
Is the special object for locking necessary here? What is difference when I used simple synchronized (this)?
Short answer: no, it's not necessary but aside from adding final I see little to no benefit to remove it.
I tend to like to use locking objects because they give me a more fine grained lock as opposed to locking on this. You might have a couple different lock objects in your class if you are, for example, protecting multiple collections from race conditions. One thing to sure is that you should always make sure to make the lock field final.
private final Object lock = new Object();
This said, if a class is simple and you want to make sure people know which methods are synchronized then using the keyword on the methods is very appropriate as well. As you mentioned, this is an internal class but even then, developers working on the outer class might want to know about the sync points.
No, it's unnecessary. Using a lock object is a pattern intended to avoid locking on the instance. Whether that is valuable often is a matter of opinion.
I'm new to Java and is trying to learn the concept of synchronisation. I saw this quote from Java Tutorial Oracle. I am struggling to understand what they are referring to by the phrase "Class object". What exactly is a class object?
You might wonder what happens when a static synchronized method is
invoked, since a static method is associated with a class, not an
object. In this case, the thread acquires the intrinsic lock for the
Class object associated with the class. Thus access to class's static
fields is controlled by a lock that's distinct from the lock for any
instance of the class.
Class<T> is a class itself. You can get class instances by:
Calling e.g. String.class (if you know the class statically), which is an instance of Class<String>
Calling someInstance.getClass() (if you want the concrete class of an instance), which is an instance of Class<? extends SomeInstance>, assuming that someInstance is a reference of type SomeInstance (the bound comes because it might be a subclass of SomeInstance).
Class is an actual class in Java. There exist objects of type Class. With each keyword-class will be associated one object of type Class (at least I assume - this makes sense and makes that block make sense).
I think the behavior makes sense - when you synchronize a static method, you certainly can't synchronize with respect to any object.
Arguably synchronized static is an antipattern. It's a program-wide bottleneck and anathema to scaleability. Say your program works well on a 1 GB server. If you want to adapt it to an 8 GB server with 256x the ports and network capacity and 8x the cores, there's no way to scale up the synchronized static code. You can't create another object, of course. I think the only solution is to spin up another process and another JVM with it.
If method have return type and it is access by two or more thread then it is required to use synchronized block or keyword with this method?
No. If that method does changes any of the field of the object that its operating upon (i.e. changing the state of object) and same object is shared amongst two thread then you might need it.
You may need to use synchronized when you are reading fields which can be changed in another thread, or writing fields which might be read in another thread. There is no specific rule of when you must, or must not use synchronized or the language would be able to do this for you. It is up to you to decide based on you use case.
It is not required. For example, if your class does not offer methods which modify instances of this class (then the class is said to be immutable) you don't need to synchronize.
However, as soon as at least one thread can write to some member variable, and there exist other threads which can read from or write to this variable at the same time, you need to synchronize the access to this variable, either by using the synchronized keyword or by manipulating locks explicitly. In some cases, you might also use atomic operation (AtomicInteger, for example).
I have a function in a class, which just masks the input card number. I have made it synchronized because, i do not want more than one thread calling my maskcard function simultaneously. My question is, should i make this function static to be more efficient and clean? Now, where ever i am calling my maskcard function, i am calling on an instance.
public class CardMasker {
public synchronized String maskCardNumber(String cardNumber)
{
..
..
}
}
A better solution would be to make sure that you have only one CardMasker instance and use non-static synchronized maskCardNumber.
I you keep the method instance specific i.e. the way you have implemented it currently :
public synchronized String maskCardNumber(String cardNumber)
Here all the threads working on same instance will access the method in synchronized fashion.
If you want to make it static synchronized, here are the points to be considered:
Does it perform operation which needs to be accessed in synchronized fashion irrespective of any instance of this class. If yes, then there is no point keeping it instance specific, because threads using different instances of this class will still be able to call the method simultaneously.
My question is, should i make this function static to be more efficient and clean?
No. It won't make it more efficient. The difference in speed (if there is any at all) will be negligible.
Furthermore, if you then make the method synchronized, you are creating a concurrency bottleneck. This doesn't need to happen in the non-static case; for example if you resist the temptation to "save space" (or something) by using a singleton. Indeed, if each thread has its own thread-confined instance of the class that implements this helper method, then the method probably doesn't need to be synchronized at all.
Also, it is a matter or opinion, but static methods are not more "clean" than instance methods.
I've problem understanding the following piece of code:-
public class SoCalledSigleton{
private final static boolean allDataLoaded = SoCalledSigleton();
private SoCalledSigleton(){
loadDataFromDB();
loadDataFromFile();
loadDataAgainFromDB();
}
}
Is this piece of code thread safe? If not then Why?
This will create an error in Java.
private final static boolean allDataLoaded = SoCalledSigleton();
You're assigning an object to a boolean variable.
You forgot to add new to instantiate the variable.
But if your code is like this
public class SoCalledSigleton{
private final static SoCalledSigleton allDataLoaded = new SoCalledSigleton();
private SoCalledSigleton(){
loadDataFromDB();
loadDataFromFile();
loadDataAgainFromDB();
}
}
It is thread-safe as static initialization and static attributes are thread-safe. They are initialized only once and exists throughout the whole life-cycle of the system.
The code is unusable in its current form, so any notions of thread safety are irrelevent.
What public interface would users use to get an instance of the singleton?
(I assume that allDataLoaded is meant to be a SoCalledSigleton and boolean is just a typo :-)
If the class has no other constructors, or the loadData* methods don't do funny business (such as publishing this), its initialization is thread safe, because the initialization of final static data members is guarded by the JVM. Such members are initialized by the class loader when the class is first loaded. During this, there is a lock on the class so the initialization process is thread safe even if multiple threads try to access the class in parallel. So the constructor of the class is guaranteed to be called only once (per classloader - thanks Visage for the clarification :-).
Note that since you don't show us the rest of the class (I suppose it should have at least a static getInstance method, and probably further nonstatic members), we can't say anything about whether the whole implementation of the class is thread safe or not.
From what we can see, there are no specific issues - it's guaranteed that the constructor will only ever by called once (so by definition can't be run multithreaded), which I presume is what you were concerned about.
However, there are still possible areas for problems. Firstly, if the loadData... methods are public, then they can be called by anyone at any time, and quite possibly could lead to concurrency errors.
Additionally, these methods are presumably modifying some kind of collection somewhere. If these collections are publically accessible before the constructor returns, then you can quite easily run into concurrency issues again. This could be an issue with anything exception updating instance-specific fields (static fields may or may not exhibit this problem depending where they are defined in the file).
Depending on the way the class is used, simply writing all of the data single-threaded may not be good enough. Collection classes are not necessarily safe for multi-threaded access even if read-only, so you'll need to ensure you're using the thread-safe data structures if multiple threads might access your singleton.
There are possibly other issues too. Thread-safety isn't a simple check-list; you need to think about what bits of code/data might be accessed concurrently, and ensure that appropriate action is taken (declaring methods synchronized, using concurrent collections, etc.). Thread-safety also isn't a binary thing (i.e. there's no such thing as "thread safe" per se); it depends how many threads will be accessing the class at once, what combinations of methods are thread-safe, whether sequences of operations will continue to function as one would expect (you can make a class "thread safe" in that is doesn't crash, but certain return values are undefined if pre-empted), what monitors threads need to hold to guarantee certain invariants etc.
I guess what I'm trying to say is that you need to think about and understand how the class is used. Showing people a snapshot of half a file (which doesn't even compile), and asking them to give a yes/no answer, is not going to be beneficial. At best they'll point out some of the issues for you if there are any; at worst you'll get a false sense of confidence.
Yeah, it's thread safe. The "method" is the constructor, and it will be called when the class is loaded, i.e. exactly once.
But looking at the stuff being done, I think it's probably a lousy idea to call it from the class loader. Essentially, you'll end up doing your DB connection and stuff at the point in time when something in your code touches the SoCalledSingleton. Chances are, this will not be inside some well-defined sequence of events where, if there's an error you have catch blocks to take you to some helpful GUI message handling or whatever.
The "cleaner" way is to use a synchronized static getInstance() method, which will construct your class and call its code exactly when getInstance() is called the first time.
EDIT: As The Elite Gentleman pointed out, there's a syntax error in there. You need to say
private final static SoCalledSingleton allDataLoaded = new SoCalledSigleton();