I have some confusion regarding thread Synchronization. Consider i have two thread Thread1 and Thread2 and two method synchronized foo1() and foo2(). foo1() is synchronized method and foo2() is not, in foo1 internally there is a statement which calls foo2() and if Thread1 calls foo1() and in that it is working in foo2() method, at the same time Thread2 want to access foo2() method directly which is not synchronized.
So my question is
will Thread2 get access of Foo2()? or it will wait for Thread1 to complete its task?
If foo2() is not synchronized, any thread can call it any time without being blocked. It doesn't make any difference whether a thread is calling it from another method which is itself synchronized.
It is the object, not the method which is locked. This means you can have the two threads in foo1() if they are accessing different objects. If they are accessing the same object, the same lock will prevent concurrent access regardless of what is called first or what calls it.
BTW: foo1() can call itself as it already has the lock.
Thread2 won't be blocked and won't wait.
It will start execution Foo2, since it's not synchronized.
Thread2 can call foo2() directly,because foo2() not a synchronized method,so any thread can call it and not acquire the current object's monitor。
Related
I was studying reentrant locking in Java. Need certain clarification on this concept that how actually it works. What all I understand for below snippet :
class Test{
public synchronized a(){
some code;
b();
some code;
}
public synchronized b(){
some code;
}
}
Above code has this scenario of reentrant lock issue.
What I understand here is, suppose we had Two Threads: T1 and T2 in application executing on Test shared object.
Whoever T1 or T2 acquires lock acquire on both a() and b(). Let say T1 first and executing a(). While execution of a() control reaches to b(); call. Now in that case T1 expecting a new Lock for this b(), or since it already had lock over b() so locking is skipped.
Need help with detailed explanation of this behavior along with issue in above code . Also how reentrant locking mechanism will help here along with snippet and detailed explanation for that as well.
A reentrant lock is one that allows a thread to acquire the lock again (many times) when it already holds the lock.
For example, if thread T1 calls a() on an object, the a() method acquires the lock on the object, and starts executing the body. When the body of a calls b(), the b() call "reentrantly" acquires the same lock. When the b() call returns, the a() call is still holding the lock. The lock is only released when the a() call returns.
(Hypothetically, if Java primitive locks were not reentrant, then the sequence T1 calls a() which then calls b() would probably either deadlock, or throw an exception ...)
Reentrant locks are typically implemented with a reference count which tells the locking implementation how deep the reentrancy is.
See also: https://stackoverflow.com/a/16504266/139985
If the lock wasn't re-entrant, the thread wouldn't be able to call b() while holding the lock it acquired when entering a().
When a() is called, and it call b() you need a lock which is reentrant or the thread will live lock itself try to acquire the lock a second time. Instead of trying to get the lock again, it instead recognises it already has a lock increments a counter so that when b() exists, it doesn't release the lock but instead decrements the counter.
I have two methods Synchronized and non-synchronized. Two threads t1 accessing Synchronized method and t2 with non-synchronized method. Will T2 wait till T1 finishes and exits synchronized block? How is this done?
All synchronized blocks synchronized on the same object can only have one thread executing inside them at a time. All other threads attempting to enter the synchronized block are blocked until the thread inside the synchronized block exits the block.
Only if t1 and t2 are trying to access same synchronized method of same object, then other have to wait until first one finishes it's job. However, this is not case as per your question. See here http://www.geeksforgeeks.org/synchronized-in-java/
Synchronized method will effect only threads using this method, therefore in your case T2 isn't using the method and won't wait for T1
Read more about Synchronized Methods
When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block
If a thread is executing a synchronized method, will it release the lock of that object before fully completing the execution of that method ? If yes, in what kind of case ?
If one thread(A) is executing synchronized method and at same time other thread(B) tries to access same synchronized method (or any other synchronized method in that object) it will go to BLOCKED state, but if the other thread(B) tries to access non-synchronized method will it get the execution before the first thread(A) completes the execution of the synchronized method ? Or it will get the execution only after the first thread(A) completes the execution of synchronized method ?
A synchronized method is just a shortcut way of writing a synchronized block (see https://stackoverflow.com/a/26676499/801894). So, no matter whether you are talking about a synchronized instance method, or a synchronized static method or a synchronized block, you really are talking about the same thing in all three cases.
Java will never allow more than one thread to be synchronized on the same object at the same time. The only tricky part of understanding that rule is to know that if a thread calls foo.wait() from inside a synchronized(foo){...} block, then the thread will not be synchronized for some interval of time while it is inside the foo.wait() call. But, it is guaranteed that the thread will synchronize on foo again before the foo.wait() call returns.
The only other way a thread can give up its synchronization of foo is to leave the synchronized(foo) {...} block altogether.
I need to clear a few basic concepts so as to check whether my understanding is correct or not.
1) Once a thread enters any synchronized method on an instance, no other thread can enter any other synchronized method on the same instance.
2) However, nonsynchronized methods on that instance will continue to be callable (by other threads). If yes, can I then say the whole object doesn't gets locked but only the critical methods which are synchronized.
3) Will I get the same behaviour as above for synchronized statement too:
synchronised(this){
// statements to be synchronised
}
or the whole object gets locked here with nonsynchronized methods on that instance not callable.
I think I am pretty confused with locking scope.
A lock only prevents other threads from acquiring that same lock -- the lock itself has no idea what it protects -- it's just something that only one thread can have. We say the whole object is locked because any other thread that attempts to lock the whole object will be unable to acquire that lock until it's released. Otherwise, your understanding is correct.
Your statements are correct. Only synchronized code becomes protected. The object is simply used as the synchronizing lock, and it is not itself "locked".
And yes, you get the same behavior for synchronized blocks on the same object. In fact, you can synchronize blocks in the code of one object using another object as the lock.
The code,
public synchronized void abc() {
...
}
it is conceptually same as,
public void abc() {
synchronized(this) {
}
}
In either of these cases the non-synchronized methods can be called when the monitor (in this case the object on which the method abc is called) is locked by a Thread executing a synchronized block or method.
Your understanding is correct. All three statements you made, are valid.
Please note one thing though, locks are not on methods(synchronized or non-synchronized). Lock is always on the object, and once one thread acquired the lock on an object, other threads have to wait till the lock is released and available for other threads to acquire.
So lets say I have this code:
public void bar(){
synchronized(foo){foo.remove(0)}
}
public void doStuff(){
synchronized(foo){
bar()
}
}
Will synchronized realize that the current chain I'm in has this lock and inherit it or will it deadlock?
The lock you get from a synchronized block is reentrant. This will not dead-lock, a thread can acquire a lock on the same object multiple times.
See Intrinsic Locks and Synchronization.
As Mat said it won't dead lock.
How i see it as
that this lock mechanism isn't dependent over method call but
on control flow.
How a single thread is executing statements and when a thread
encounters a synchronized block then it ask for the lock of the object in the synchronized signature.
If it has it then it enters else will wait in the lock pool of the object until gets notified.
thread which executed doStuff() already carried the lock so thats why no case of deadlock