I was reading about JAVA synchronization.
I have 2 methods in my class.
public synchronized void eat()
{
System.out.println("eat");
eatDinner();
}
public synchronized void eatDinner()
{
System.out.println("eat");
}
Both of my methods are synchronized.
Now Is it possible for 2 threads one is calling eat() and another eatDinner() to run simultaneously?
And If thread2 has not still executing eatDinner() . Can thread1 can call eatDinner() from eat()?
No, it is not possible for two threads to run the methods eat and eatDinner simultaneously. (Caveat: as long as these methods are invoked on the same instance of the class)
The synchronized keywords, when applied to a non-static method, synchronizes on the object itself.
Your code can be rewritten, without changing the meaning, as:
public void eat() {
synchronized (this) {
System.out.println("eat");
eatDinner();
}
}
public void eatDinner() {
synchronized (this) {
System.out.println("eat");
}
}
This probably makes it easier to see that they are both synchronizing on the same monitor.
Each java object has a monitor.
As long as 'thread1' is holding the monitor of your object, it can enter other synchronized blocks on the same monitor. 'thread1' has to exit all synchronized blocks (exist the blocks as many times as it has entered them) before another thread can take ownership of the monitor.
So thread1 can call eatDinner if it is already in the eat method - no problem. But if thread2 is currently in the eat method, then thread1 will block when it calls eatDinner until thread2 has finished both eatDinner and eat.
Addition:
In response to your comment
#Raj: If two threads are created by same class instances, then?
It is not important how the threads were created - it doesn't matter if that happened from within the same class or from completely different locations in your code. Two different threads are always independent.
It only matters on which object's monitor you synchronize: each object instance has one 'monitor'. You can't see this monitor - it doesn't have a name, but it's there and it is used by the synchronized keywords and by the wait, notify and notifyAll methods defined in java.lang.Object.
"Now Is it possible for 2 threads one is calling eat() and another eatDinner() to run simultaneously? "
on the same instance, no. they will block and only one will execute at once. different class instances, yes, they will not block eath other.
"Can thread1 can call eatDinner() from eat()"
yes. the lock is reentrant.
If 2 threads call methods on different class instances they can run methods simultaneously
Related
Why sleep() and yield() methods are defined as static methods in java.lang.Thread class?
The code would only execute when someXThread was executing, in which case telling someYThread to yield would be pointless. So since the only thread worth calling yield on is the current thread, they make the method static so you won't waste time trying to call yield on some other thread.
This is because whenever you are calling these methods, those are applied on the same thread that is running.
You can't tell another thread to perform some operation like, sleep() or wait. All the operation are performed on the thread which is being executed currently.
If you call the yield or sleep method, it applies to whichever thread is currently executing, rather than any specific thread - you don't have to specify which thread is currently running to free up the processor.
similar thread in this forum
The same reason is why stop() and suspend() methods are deprecated. Intrusion in thread's state from outside is dangerous and can cause unpredictable result. And if sleep is not static, for example, how do you think interruption from it will happen?
They are static so that overriding concept can be avoided i.e.
When they are called with parent class reference to hold child class object like situation it implements Method Hiding concept and not overriding due to Static method nature, i.e parent class(here thread class) method will run which have the complete functionality of sleep and yield.
http://i.stack.imgur.com/goygW.jpg
Both sleep and yield methods are native. To understand better from above answers I made two classes ClassA and ClassB with same static method. I invoked method of other class to check its behavior. So we can call other class' static method.
So may be there is other reason behind making sleep method static.
public class ClassA {
public static void method(){
System.out.println("Inside ClassA method");
}
public static void main(String[] args) {
method();
ClassB classb = new ClassB();
classb.method();
}
}
public class ClassB {
public static void method(){
System.out.println("Inside ClassB method");
}
}
I know I am late to this party, (blame my parent :-))
I would like to answer this using proof by contradiction.
Let's say sleep method is not static so you can call sleep on any other thread object.
Let's say there are two threads, thread A and thread B. Now consider two possible scenarios in the context of sleep method, the same applies to yield as well.
System having single processor has only one thread active at a time, so if thread A calls sleep on thread B object i.e. B.sleep(), B is not in execution, as currently executing thread is thread A, so calling sleep on non-executing method is pointless.
A responsible programmer would never define sleep inside a synchronized block, or when a thread is holding a lock. But let's say thread A calls sleep method on thread B just when thread B is holding a lock(or inside a synchronized block), thread B would go to sleep holding lock which is totally undesirable.
These are just a few situations which forced jvm to not allowed thread to call sleep on another thread obect.
I have a class as
public class ThreadExample extends Thread{
static int count = 0;
public static synchronized int increment(){
return count++;
}
public synchronized int decrement(){
return count--;
}
}
Here I have one static method and one non-static method.
First thread1 have called method increment() which is synchronized.It acquires lock on class level.
Here my question is if another thread2 is calling decrement() method will that thread2 will acquire lock on decrement() and how it works?
The synchronized keyword has two possible uses. It can be used as a modifier for methods, and it can be used as a statement. Besides, the synchronized modifier can be combined with static, and in that case the target object will be the enclosing class instead of the enclosing instance.
Scope | modifiers | corresponding statement
---------+---------------------+------------------------
static | synchronized static | synchronized (X.class)
instance | synchronized | synchronized (this)
If a method is static synchronized, the lock is acquired on the class object of the enclosing class, in your case on ThreadExample.class.
Although they're compiled into different byte code, the following two methods are equivalent:
public class Foo {
// static method with synchronized modifer
public static synchronized void foo1() {
// ...
}
// equivalent synchronized statement
public static void foo2() {
synchronized (Foo.class) {
// ...
}
}
}
If a method is synchronized (without static), the lock is acquired on the instance itself. Although they're compiled into different byte code, the following two methods are equivalent:
public class Foo {
// instance method with synchronized modifier
public synchronized void foo3() {
// ...
}
// equivalent synchronized statement
public void foo4() {
synchronized (this) {
// ...
}
}
}
So, increment() and decrement() are synchronized differently, and there can be a race condition.
Therefore, the variable count is not sufficiently protected from concurrent update.
++ and -- cannot be atomic themselves, as incrementing or decrementing a value requires a read-update-write cycle. Technically it could be atomic because some CPUs provide atomicity for that by providing corresponding instructions which will keep the bus / address obtained for themselves until the operation is performed. But the JVM does not rely on such things.
If you need a atomic int, you might want to look at java.util.concurrent.atomic.AtomicInteger.
How to do synchronized in C
synchronized is implemented with the VM environment methods MonitorEnter() and MonitorExit().
Pitfalls
When you use the synchronized modifier, you synchronize on something which is more or less public, i.e. visible to other objects and classes as well. The Monitor feature of java.lang.Object which provides the underlying facility for synchronized is public, as well as the native functions MonitorEnter() / MonitorExit() and the wait pool methods wait(), notify() and notifyAll(). This can lead to unexpected bugs and deadlocks if "somebody else" is also using "your object / your class" for synchronization.
Therefore it has become a pattern to actually not use the synchronized modifier but instead use synchronized statements on a private lock object, like this:
public class Foo {
private final Object lock = new Object();
public void foo() {
synchronized (lock) {
// ...
}
}
}
Now Foo can no longer be disturbed or blocked by somebody else synchronizing on it. You might think there might be a reasonable use case for that, but I think if you have a use case for locking across object / class boundaries, there's probably a big flaw in the design - things are not self-contained enough.
If you need a class lock instead of an instance lock, just make the variable static.
Note that when doing serialization, you will have to take care of the lock object. The simplest way is to actually not use Object, but this:
public class Lock implements Serializable {}
If you want to save serialization storage, you can declare the lock transient and recreate the lock during deserialization, but be careful about transient final, you need reflection or readResolve() for them, but that's a different story.
Calling synchronized static methods tries to acquire the lock of the class object. (ThreadExample in your case), while calling synchronized non-static methods tries to acquire the lock of the particular instance object. So essentially you are acquiring 2 different locks and thus your code is not thread-safe. The data count may be corrupted due to race condition
Oracle tutorial:
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.
Static and instace level locks are two different locks and they are independant of each other.
Regarding scenario in question "First thread1 have called method increment() which is synchronized.It acquires lock on class level. Here my question is if another thread2 is calling decrement() method will that thread2 will acquire lock on decrement() and how it works"
even if thread1 is holding (class level)lock on increment method and thread2 calls decrement method it should aquire a (instance level)lock .
problem is not with aquiring the lock problem might start when they are trying to updated the shared variable.If two threads are trying to access count variable (one through static locking and other through instance level locking ) at a same time then there might be a RACE condition between two threads.
As suggested by Christian you can overcome this by using java.util.concurrent.atomic.AtomicInteger instead of int
For more details please visit URL
A static synchronized method and a non-static synchronized method will not block each other. The reason is static method locks on a Class instance while the non-static method locks on the this instance— both actions do not interfere with each other at all.
In your code one method is static synchronized and another method is just synchronized. Your code is not thread safe, even if two threads are executing two methods on same object, one thread (executing non-static method) acquires object level lock and proceed. Another thread executing static method acquires class level lock (i.e. ThreadExample.class ) and proceeds. Remember that static methods are always class level.
To make your code thread safe you need to have below changes in your example.
public static synchronized int decrement(){
return count--;
}
1) If a class (say TestClass) has two methods (method1, method2). Two threads (t1, t2) are running parallely where t1 is calling method1 of an object object1 (of type TestClass), and t2 is calling method2 of the same object (object1).
What happens if, only method1 is synchronized, and method2 is not?
If both methods are synchronized, then will both run parelley? (its not running, but why?, we can achieve this with two dummy objects and block level synchronization)
In the below, method1 and method2 of a same object can be executed parallely with two threads?
void method1() {
synchronized(object1) {
....
}
}
void method2() {
synchronized(object1) {
....
}
}
What is the usage of synchronized block with .class synchronized(TestClass.class) { }
If only method1 is synchronized, then method2 and method1 can be executed in parallel.
If both methods are marked synchronized they cannot run in parallel.
I think what's confusing you here is the synchronized keyword. A synchronized method will be synchronized for that instance of class. Like so:
synchronized void Method1(){}
synchronized void Method2(){}
These methods can only be entered if the instance they're defined in is not being used to execute a synchronized block of code elsewhere. Compare that to this:
void Method1(){
//can run in parallel
synchronized(this){
//cannot run in parallel.
}
//can run in parallel.
}
void Method2(){
synchronized(this){
//cannot run in parallel.
}
}
This is not quite the same. Both methods can be entered, but code within the synchronized block cannot run in parallel.
Lastly, if you synchronize on TestClass.class it will prevent code anywhere synchronizing on the same object from executing. This is true when synchronizing on any static object.
they can run concurrently
no, only one thread can have the lock of the object at a time. So, while one thread executes method1 or method2, no other trhread can execute any of these two methods on the same object.
no, since they both need to have the lock of the same object to execute
To prevent other threadd to execute static synchronized methods of the TestClass concurrently, or any block synchronizing on the same Class object.
As long the methods do not change state of the/any object in common scope, there is no need to sync. The interessting part is in .....
I have three threads on the same class i.e
Thread A obj, Thread B obj, Thread C obj and that class contains 3 static synchronized methods so when we start the 3 threadssaya.meth1, b.meth2, c.meth3what will happen – does all three will execute or only one ?`
Update:
interviewr asked me this question so actually i do have any code to write it here
The methods are static and synchronized.. So, the lock will be on the class object.. Not on the instances of the class.. So the methods will run one after another.... Thread2 and Thread3 will have to wait until thread1 completes method1().. syncronization is NOT at method level.. it is always at object level... beit instance object or class object.
then they will execute it one by one in serial manner as the methods are static synchronized. So the lock will be held at Class Level not the method level. Hence one thread will acquire lock and others will have to wait.
You should try running this and see.
Once you invoke a synchronized method, the VM will automatically ask a grant of access for the object on which you are invoking the method. If that is given it will enter the synchronized method. Upon exit til will release this access right. While holding the rights, no-one else is allowed into any synchronized method on the same object, effectively serializing the requests.
does that make sense?
Synchronization is designed to make things thread-safe and avoid race conditions, and this fashion reduce access to at most one thread. There is no way for the program to find out whether two synchronized methods A and B are otherwise connected, so it has the policy of least tolerance.
If you have more synchronization that necessary, e.g. that A and B needs to be mutually exclusive and C and D needs to be mutually exclusive, but not between, say A and C then the advice is typically to modularise your code so A+B goes into one object while C+D goes into another, hence avoiding to step over each others toes
If execution for objects of the same class attempt to enter the same synchronized method (whether static or not)from different threads, they will be synchronized (i.e. execute one at a time).
The primary difference between static synchronized methods and non static synchronized methodsis that non-static synchronized methods hold a lock on the instance of the class whereas static synchronized methods lock on the class object.
Since in java there exists one class object per class, only one thread can execute inside a static synchronized method in the same class.
For non-static synchronized methods only one thread can execute inside a static synchronized method in the same object
And one more point is that synchronization is at object level not as method level.
I was reading though a book on Java and there was this exercise question where they declared a class with one private variable, one public void method that did some expensive operation to calculate and then set the private variable, and a second public method to return the private variable. The question was "how can you make this thread-safe" and one possible answer was "synchronize each of the two methods" and one other possible answer was "this class can not be made thread-safe".
I figured the class could not be made thread-safe since even if you synchronize both methods, you could have a situation that Thread1 would invoke the setter and before Thread1 could invoke the getter, Thread2 might execute and invoke the setter, so that when Thread1 went and retrieved the result it would get the wrong info. Is this the right way to look at things? The book suggested the correct answer was that the class could be made thread safe by synchronizing the two methods and now I'm confused...
I figured the class could not be made thread-safe since even if you synchronize both methods, you could have a situation that Thread1 would invoke the setter and before Thread1 could invoke the getter, Thread2 might execute and invoke the setter, so that when Thread1 went and retrieved the result it would get the wrong info. Is this the right way to look at things?
You are correct with this. There is no way to guarantee that a thread will not have called either of the methods in between your calls of each of the methods, from within the class.
If you do want to do this, that will require a wrapper class.
So if the class with the getter and setter is like so:
class Foo
{
private static int bar;
public static synchronized void SetBar(int z) { ... }
public static synchronized int GetBar() { ... }
}
The wrapper class would look something like this:
class FooWrapper
{
public synchronized int SetGetBar(int z)
{
Foo.SetBar(z);
return Foo.GetBar();
}
}
The only way to guarantee this will work is if you can guarantee that all calls will go through your wrapper class rather than directly to class Foo.
When you make those two synchronized, the getter and setter themselves are thread-safe. More specifically:
When you call the setter, you are guaranteed that the value of the variable is what you set it to when the method finishes.
When you call the getter, you are guaranteed that the return value is the value of the variable when you made the call.
However, making the getter and setter themselves thread-safe does not mean that the application as a whole (i.e. whatever is using this class) is thread-safe. If your thread wants to call a setter then get the same value upon invoking the getter, that involves synchronization on a different level.
As far as thread-safety is concerned, a thread-safe class need not control how its methods are invoked (for example, it need not control which way the threads interleave their calls), but it needs to ensure that when they are, the methods do what they are supposed to.
synchronized in Java is an object-wide lock. Only one synchronized method of any given object can be executed on any given thread at a time. Let's have this class:
class Foo
{
private int bar;
public synchronized void SetBar() { ... }
public synchronized int GetBar() { ... }
}
Thread 1 calls SetBar(). Thread 1 acquires the object lock.
Thread 2 wants to call SetBar(), but Thread 1 holds the lock. Thread 2 is now queued to acquire the lock when Thread 1 will release it.
Thread 1 finishes executing SetBar() and releases the lock.
Thread 2 immediately acquires the lock and starts executing SetBar().
Thread 1 calls GetBar(). Thread 1 is now queued to acquire the lock when Thread 2 will release it.
Thread 2 finishes executing SetBar() and releases the lock.
Thread 1 acquires the lock, executes GetBar(), and is done with it.
You did the work twice, but you didn't cause any race condition. It may or may not be erroneous to do the work twice, depending on what it is.
A frequent pattern is to have one thread produce content and one other thread do something useful with it. This is called the producer-consumer pattern. In this case, there is no confusion over who or what tries to SetBar() and what tries to GetBar().