I want to understand how locking is done on static methods in Java.
let's say I have the following class:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() { return bar; }
It's my understanding that when I call f.get(), the thread acquires the lock on the object f and when I do Foo.inc() the thread acquires the lock on the class Foo.
My question is how are the two calls synchronized in respect to each other?
Is calling a static method also acquires a lock on all instantiations, or the other way around (which seems more reasonable)?
EDIT:
My question isn't exactly how static synchronized works, but how does static and non-static methods are synchronized with each other.
i.e., I don't want two threads to simultaneously call both f.get() and Foo.inc(), but these methods acquire different locks. My question is how is this preventable and is it prevented in the above code.
Static and instance synchronized methods are not related to each other, therefore you need to apply some additional synchronization between them, like this:
class Foo {
private static int bar = 0;
public static synchronized void inc() { bar++; }
public synchronized int get() {
synchronized (Foo.class) { // Synchronizes with static synchronized methods
return bar;
}
}
}
(though in this case leaving synchronized on get() doesn't make sense, since it doesn't do anything that requires synchronization on instance).
Beware of deadlocks - since this code aquires multiple locks, it should do it in consistent order, i.e. other synchronized static methods shouldn't try to acquire instance locks.
Also note that this particular task can be solved without synchronization at all, using atomic fields:
class Foo {
private static AtomicInteger bar = new AtomicInteger(0);
public static void inc() { bar.getAndIncrement(); }
public int get() { return bar.get(); }
}
A synchronized static method is effectively equivalent to:
public static void foo() {
synchronized (ClassName.class) {
// Body
}
}
In other words, it locks on the Class object associated with the class declaring the method.
From section 8.4.3.6 of the JLS:
A synchronized method acquires a monitor (ยง17.1) before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (the object for which the method was invoked) is used.
If you read http://download.oracle.com/javase/tutorial/essential/concurrency/locksync.html.
It will tell you:
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.
which tells you all you need to know.
Neither, the non-static synchronized call does not acquire a lock on the class itself. (And the static synchronized block does not lock any object instantiated from that class.)
In other words the calls f.get() (locks f) and Foo.inc() (locks the class Foo) can run concurrently. They are not "synchronized".
You could use a different pattern (singleton), or make all the methods static.
Static locks are attached to the class definition and thus is shared between all instances of that class.
Synchronization of none static methods only apply to the current instance of the class (the lock is on the class instance, e.g., this). In your example you have two different locks with no interrelation.
I don't want two threads to simultaneously call both f.get() and Foo.inc(), but these methods acquire different locks. My question is how is this preventable and is it prevented in the above code
You must share a lock to be able to arbitrate access to both f.get and Foo.inc(). You can do this either by sharing the same static lock or by the same instance lock.
These two calls do not synchronize in respect to each other.
It is as you said, a caller of f.get() acquires the lock of f object and caller of Foo.inc() acquires Foo.class object's one. So the synchronization rules are the same as if instead of static call you called an instance synchronized method with another object.
Related
If I have a class that has 2 methods say setA and setB that have synchronized but they are not synchronized on the same object, how do I lock it such that if there were two instances of the class, methods setA and setB cannot happen simultaneously?
In short, you can use a synchronized (lockObj) {...} block in the body of both methods, and use the same lockObj instance.
class MyClass {
private final Object lock;
public MyClass(Object lock) {
this.lock = lock;
}
public void setA() {
synchronized (lock) {
//...
}
}
public void setB() {
synchronized (lock) {
//...
}
}
}
Few things to note:
The lock needs not to be static. It is up to your implementation how you provide it. But every MyClass instance must use the same lock instance if you want them to prevent threads from executing their blocks simultaneously.
You can not use synchronized methods in this case, since each non static synchronized method will use its on this instance's monitor.
If you want to access other instance members, you can not use static synchronized methods either.
You can still synchronize on another object within the class that you create.
Object lock = new Object();
Then just synchronize on the lock object.
If you want to get a bit more into it you can use the util.concurrency libraries.
Check out Semaphores or Latches, depends on what you want to do with your setA and setB
Multiple ways.
1) You can synchronize the methods: public synchronized void setA()
Doing that means that only one thread can enter the method at a time (good and bad)
2) A better solution would be to use a ReentrantLock:
ReentrantLock lock = new ReentrantLock();
void public void setA() {
lock.lock();
try {
//Do Something
}
finally {
lock.unlock();
}
}
There are other ways as well.
You can check the Java tutorial on concurrency:
https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
Another decent posting:
http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/
Good luck!
Synchronize them on a single, static reference. A private static final Object lock = new Object () will do, as Will just TheClass.class.
This will also mean that no two threads can invoke setA at the same time, even if nobody is invoking setB. If that's not acceptable, you can use a (static) read-write lock for finer-grained access. setA uses the read lock, and setB uses the write lock; that means that any number of threads can invoke setA, but only one can invoke setB. You probably don't want the reverse to also be true, because that's susceptible to deadlocking.
I have less experience of multi-thread programming. I have multi-threads to write to a file. And I was wondering what's the difference between:
Implement 1: a class with static synchronized function. And each thread call FileUtil.writeToFile()
public class FileUtil {
public static synchronized void writeToFile(String filename) {
// write to file....
}
}
Implement 2: A singleton class. And each thread call Fileutil.getInstance().writeToFile()
public class FileUtil {
private static final FileUtil fileManager = new FileUtil();
private FileUtil() {
}
public synchronized void writeToFile(String filename) {
// write to file....
}
public static FileUtil getInstance() {
return fileManager;
}
}
There is no practical difference.
In practice, either way, you have one unique lock object that all callers must acquire in order to enter the method.
The only difference is the identity of the lock object: In the singleton case, the lock object is the singleton. In the static method case, it's the Class object.
The issues in your question can be divided into:
Should I use a class with static methods or the singleton pattern? This has already been discussed, for example in Difference between static class and singleton pattern?.
Is there a difference between the two synchronizations? Well, one locks on a class, the other on an object. And as Sotirios Delimanolis linked in the comments, it's discussed in Java synchronized static methods: lock on object or class.
Regarding the choice of monitor, there is a third option:
Use a monitor object that is not accessible to the caller. The advantage of this is that if the user of the class or the singleton decides to use that class or that singleton as a monitor in his own program, it won't cause all calls to writeToFile() to be blocked.
That is, suppose somebody does this:
FileUtil obj = FileUtil.getInstance();
synchronized ( obj ) {
// Some long operation
}
Because the writeToFile() method synchronizes on that same instance, no other thread will be able to use writeToFile() until the "long operation" is done and the synchronized block is left.
Now, instead, if you did this:
public class FileUtil {
private static final FileUtil fileManager = new FileUtil();
private static final Object lock = new Object(); // To be used for synchronizing
private FileUtil() {
}
public void writeToFile(String filename) {
synchronized (lock) {
// write to file....
}
}
public static FileUtil getInstance() {
return fileManager;
}
}
then even if the user of your class decides to use it as a lock (be it the class monitor or an instance monitor), it's not going to interfere with the functionality of writeToFile().
In short, there is no real difference.
The thing to note here is that in synchronization number 1 (static synchronized method), all threads would compete on acquiring the lock on the Class object (that represents the FileUtil class) and only one thread will acquire the lock at a time and execute the method.
In the second case all threads would again compete on acquiring the monitor associated with the "this" object (and only one thread will acquire it and execute at a time). Note we are talking about a singleton so there is exactly one instance in this address space (there could be more than one instance if this class is loaded through more than one classloaders as well but we digress).
In either case all the threads are competing to acquire a lock on exactly one object: the class description object or the "this" object and therefore there is no real difference when you run the program. There is a slight heap difference in that an instance of the FileUtil is created in the second case and put on the heap but that is inconsequential.
Both are equivalent in delivering the same result.
But I prefer second implementation of Singleton class + RealSkeptic suggestion to have static final lock object.
Advantage with Singleton : In future, you can change Singleton to ObjectPool of FileUtil with a certain size (e.g.: 5 objects of FileUtil). You have more control with pool of FileUtil with static Object lock compared to static synchronized method in first implementation.
I have a question in singleton pattern.
In singleton pattern we write
synchronized(ClassName.class){
// other code goes here
}
What is the purpose of writing ClassName.class?
In a member method (non-static) you have two choices of which monitor (lock) to use: "this" and "my class's single static lock".
If your purpose is to coordinate a lock on the object instance, use "this":
...
synchronized (this) {
// do critical code
}
or
public synchronized void doSomething() {
...
}
However, if you are trying to have safe operations including either:
static methods
static members of your class
Then it is critical to grab a class-wide-lock. There are 2 ways to synchronize on the static lock:
...
synchornized(ClassName.class) {
// do class wide critical code
}
or
public static synchronized void doSomeStaticThing() {
...
}
VERY IMPORTANTLY, the following 2 methods DO NOT coordinate on the same lock:
public synchronized void doMemberSomething() {
...
}
and
public static synchronized void doStaticSomething() {
...
}
Each class (for example Foo) has a corresponding, unique instance of java.lang.Class<Foo>. Foo.class is a literal of type Class<Foo> that allows getting a reference to this unique instance. And using
synchronized(Foo.class)
allows synchronizing on this object.
The object that you pass into the synchronized block is known as a monitor. Since the object that represents the class className.class is guaranteed to only exist once in the JVM it means that only one thread can enter that synchronized block.
It is used within the singleton pattern to ensure that a single instance exists in the JVM.
class MyClass
{
public synchronized void print() {}
public static synchronized void buffer() {}
}
Making static object synchronized makes a CLASS level object where only one Thread can access this. The class has both static and non-static Synchronized methods.
Can other threads(Thread-B) access non-static synchronize methods() via object lock while another Thread (Thread-A) using static synchronized (Acquiring a class level lock) method?
I hope non of the threads access any of the static synchronized methods until (Thread-B) release the lock.
The answers to both your questions are "yes": static-level locks do not block instance-level synchronized methods, and they apply to all static synchronized methods.
Generally, though, synchronizing on the class is discouraged, because it leaves your class exposed to an infinite wait attack. The perpetrator synchronizes on the class, preventing all your static synchronized methods from running. A better approach is to make a private object for locking, and synchronize on it, like this:
class MyClass
{
public synchronized void print() {}
private static Object staticLock = new Object();
public static void buffer() {
synchronized(staticLock) {
...
}
}
}
Same goes for synchronizing the instance methods: if the class is to be used in potentially non-cooperative environment, you are better off with a private object for locking.
In short:
non-static methods use the current object's lock (only one thread per object)
static methods use the associated Class object (there is one per class, so, only one therad per Class object)
It's important to take into account erasure:
// If you have this:
class MyClass<T> {
static synchronized myMethod() { ... }
}
MyClass<Integer> objInt = new MyClass<Integer>();
MyClass<String> objString = new MyClass<String>();
// Then only one thread will be able to execute myMethod(),
// even when ojbInt and ObjString are not "exactly" the "same"
// class in compilation time
static locks
synchronized(YourClass.class/class object)
instance locks
synchronized(this/instance object)
both are not mutually exclusive, both thread will run concurrently
What is the difference between synchronizing a static method and a non static method in java?Can anybody please explain with an example. Also is there any difference in synchronizing a method and synchronizing a block of code?
I will try and add an example to make this extra clear.
As has been mentioned, synchronized in Java is an implementation of the Monitor concept. When you mark a block of code as synchronized you use an object as a parameter. When an executing thread comes to such a block of code, it has to first wait until there is no other executing thread in a synchronized block on that same object.
Object a = new Object();
Object b = new Object();
...
synchronized(a){
doStuff();
}
...
synchronized(b){
doSomeStuff();
}
...
synchronized(a){
doOtherStuff();
}
In the above example, a thread running doOtherStuff() would block another thread from entering the block of code protecting doStuff(). However, a thread could enter the block around doSomeStuff() without a problem as that is synchronized on Object b, not Object a.
When you use the synchronized modifier on an instance method (a non-static method), it is very similar to having a synchronized block with "this" as the argument. So in the following example, methodA() and methodB() will act the same way:
public synchronized void methodA() {
doStuff();
}
...
public void methodB() {
synchronized(this) {
doStuff();
}
}
Note that if you have a methodC() in that class which is not synchronized and does not have a synchronized block, nothing will stop a thread from entering that method and careless programming could let that thread access non-safe code in the object.
If you have a static method with the synchronized modifier, it is practically the same thing as having a synchronized block with ClassName.class as the argument (if you have an object of that class, ClassName cn = new ClassName();, you can access that object with Class c = cn.getClass();)
class ClassName {
public void static synchronized staticMethodA() {
doStaticStuff();
}
public static void staticMethodB() {
synchronized(ClassName.class) {
doStaticStuff();
}
}
public void nonStaticMethodC() {
synchronized(this.getClass()) {
doStuff();
}
}
public static void unSafeStaticMethodD() {
doStaticStuff();
}
}
So in the above example, staticMethodA() and staticMethodB() act the same way. An executing thread will also be blocked from accessing the code block in nonStaticMethodC() as it is synchronizing on the same object.
However, it is important to know that nothing will stop an executing thread from accessing unSafeStaticMethodD(). Even if we say that a static method "synchronizes on the Class object", it does not mean that it synchronizes all accesses to methods in that class. It simply means that it uses the Class object to synchronize on. Non-safe access is still possible.
In short if you synchronize on a static method you will synchronize on the class (object) and not on an instance (object). That means while execution of a static method the whole class is blocked. So other static synchronized methods are also blocked.
Synchronization in Java is basically an implementation of monitors. When synchronizing a non static method, the monitor belongs to the instance. When synchronizing on a static method, the monitor belongs to the class. Synchronizing a block of code is the same idea, but the monitor belongs to the specified object. If you can get away with it, synchronized blocks are preferable because they minimize the time each thread spends in the critical section
There is virtually no difference between synchronizing a block and synchronizing a method. Basically:
void synchronized m() {...}
is the same as
void m() { synchronized(this) {...} }
By comparison a static synchronized method is the same as:
static void m() { synchronized(MyClass.class) {...} }
Dude, just a hint. Not related to your question:
If any do*Stuff() methods does either
this.a= /*yet another*/ new Object();
or
this.b= /*yet another*/ new Object();
then you are screwed. Because the lock is inside the value, not inside the reference. See Java synchronized references
From javadoc https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
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.
public static synchronized void getInstance(){}
When we acquire a lock on any class, we actually acquire a lock on "Class" class instance which is only one for all instances of class.
public synchronized void getInstance(){}
we can create multiple object's of a class and each object will have one lock associated with it.