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.
Related
Suppose you have two threads that have access to the same public object. One thread has a block of code that reads the object's fields.
synchronized(object)
{
read object fields
}
While the read object field code is executing in thread 1, if thread 2 wants to update the object's fields, will it have to wait until thread 1 finishes reading the object's fields before updating (e.g. is the object locked from access by other threads while the synchronized code block is executing)?
Synchronizing on an object does not "lock" it in any way. Unless updating the object's fields is synchronized in the same fashion, it may very well interleave with the reading code you presented here.
No, the second thread will not wait, unless it has a synchronized block on the same object too.
synchronized(object)
{
// read object fields
}
... in other thread:
synchronized(object)
{
// write object fields
}
Synchronized block only protects the code inside it. So if two or more threads try to run code inside synchronized block (protected by same object monitor) they will be executed exclusively. Meaning if one thread has entered synchronized block others will have to wait till it gets out.
Synchronized block does not lock the object in anyway, it just uses object's monitor to guard the code inside it. If you want to make method of object thread safe then you have to declare them synchronized.
synchronized getField()
synchronized setField()
Now getField() and setField() can safely be called by multiple threads.
However using synchronized has a performance cost instead you can try using Locks, or Atomic classes in java.util.concurrent.atomic like AtomicInteger, AtomicBoolean or AtomicReference.
Consider this code:
public synchronized void onSignalsTimeout(List<SignalSpec> specs) {
if (specs != null && specs.size() > 0) {
for (SignalSpec spec : specs) {
ParsedCANSignal timeoutedSignal = new ParsedCANSignal();
SignalsProvider.getInstance().setSignal(spec.name, spec.parent.parent.channel, timeoutedSignal);
}
}
}
I've got simple question:
When Thread 1 calls onSignalsTimeout method, can Thread 2 access objects that are accessed in that method?
Can't find anywhere if 'synchronized' locks only access to this method or access to all objects used in this method.
First of all, forget about synchronized methods. A so-called synchronized method...
synchronized AnyType foobar(...) {
doSomething();
}
Is nothing but a shortcut way of writing this:
AnyType foobar(...) {
synchronized(this) {
doSomething();
}
}
There is nothing special about the method in either case. What is special is the synchronized block, and what a synchronized block does is very simple. When the JVM executes this:
synchronized(foo) {
doSomething();
}
It first evaluates the expression foo. The result must be an object reference. Then it locks the object, performs the body of the synchronized block, and then it unlocks the object.
But what does locked mean? It may mean less than you think. It does not prevent other threads from using the object. It doesn't prevent them from accessing the object's fields or, from updating its fields. The only thing that locking an object prevents is, it prevents other threads from locking the same object at the same time.
If thread A tries to enter synchronized(foo) {...} while thread B already has foo locked (either in the same synchronized block, or in a different one), then thread A will be forced to wait until thread B releases the lock.
You use synchronized blocks to protect data.
Suppose your program has some collection of objects that can be in different states. Suppose that some states make sense, but there are other states that don't make sense—invalid states.
Suppose that it is not possible for a thread to change the data from one valid state to another valid state without temporarily creating an invalid state.
If you put the code that changes the state in a synchronized(foo) block, and you put every block of code that can see the state into a synchronized block that locks the same object, foo, then you will prevent other threads from seeing the temporary invalid state.
Yes, other threads can access the objects used in the method; the synchronized keyword guarantees that no more than one thread at the time can execute the code of the method.
From https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html:
First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing
a synchronized method for an object, all other threads that invoke
synchronized methods for the same object block (suspend execution)
until the first thread is done with the object.
Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent
invocation of a synchronized method for the same object. This
guarantees that changes to the state of the object are visible to all
threads. Note that constructors cannot be synchronized — using the
synchronized keyword with a constructor is a syntax error.
Synchronizing constructors doesn't make sense, because only the thread
that creates an object should have access to it while it is being
constructed.
In this context, synchronized simultaneously locks this method and any other method similarly marked as synchronized in your class.
if I have two thread A and B that use the same class C.java what happens if thread A use a synchronized method(synchro()) that access use another class method(myMethod()) and after 1ms or minus thread B try to use myMethod()? He will wait until thread A has finished or it accesses to myMethod()? Thread A and Thread B use the same class instance.
Synchronization is not implicitly transitive. It is merely a lock on the object to execute a block of code. It does not lock the objects that are used inside the code block.
Thread B will have access to the unsynchronized method. Since it's not synchronized, Thread B doesn't need to wait to acquire an object monitor.
Implicit mutex lock will be introduced only for method synchro(), but not for myMethod(), since myMethod() is not synchronized. As a consequence access to myMethod() will not be syncronized between multiple threads.
It will access it.
Only synchronized methods or synchronized blocks cannot be executed concurrently: Synchronized Methods
There is no such thing as a synchronized method.
Repeat after me: There is no such thing as a synchronized method.
When you write this:
synchronized Foobar myFunk() { ... }
That's just syntactic sugar that saves you from having to write this instead:
Foobar myFunk() {
synchronized(this) { ... }
}
But the second one makes it more obvious what is really going on: It's not the method that is synchronized, it's the object.
The JVM will not allow two different threads to synchronize the same object at the same time. That's all it means. Synchronizing an object does not "lock" the object (other threads can still modify it). Synchronizing an object does not prevent other threads from calling the same method. All it does is prevent other threads from synchronizing the same object at the same time.
How you use that feature is up to you.
Normally, you use it to protect invariants. An invariant is an assertion that you make about some value or some group of values. (e.g., the length of list L is always even). If one thread must temporarily break the invariant (e.g., by first adding one thing to the list, and then adding another), and some other thread will crash and burn if it sees the broken invariant; then you need synchronization.
The first thread only breaks the invariant while inside a synchronized block, and any other thread only looks at the data when it is synchronized on the same object. That way, the one the looks can never see the invariant in the broken state.
Can anyone tell me if I'm right or not? I have two thread which will run in parallel.
class MyThread extends Thread {
MyThread() {
}
method1() {
}
method2() {
}
method3() {
}
approach(1):
run() {
method1();
method2();
method3();
}
approach(2):
run() {
//the code of method1 is here (no method calling)
//the code of method2 is here (no method calling)
//the code of method3 is here (no method calling)
}
}
class Test{
public static void main(){
Thread t1 = new Thread();
t1.start();
Thread t2 = new Thread();
t2.start();
}
}
method1, method2 and method3 don't access global shared data but their codes perform some write in local variable within the method section, thus I guess I can not allow overlap execution within the method section.
Thereby:
in approach(1): I need to make the methods (method1, method2 and method3) synchronized, right?
in approach(2): No need to synchronize the code sections, right?
If I'm right in both approach, using the approach(2) will give better performance, right?
Short answer: you don't need the synchronization. Both approaches are equivalent from a thread safety perspective.
Longer answer:
It may be worthwhile taking a step back and remembering what the synchronized block does. It does essentially two things:
makes sure that if thread A is inside a block that's synchronized on object M, no other thread can enter a block that's synchronized on the same object M until thread A is done with its block of code
makes sure that if thread A has done work within a block that's synchronized object M, and then finishes that block, and then thread B enters a block that's also synchronized on
M, then thread B will see everything that thread A had done within its synchronized block. This is called establishing the happens-before relationship.
Note that a synchronized method is just shorthand for wrapping the method's code in synchronized (this) { ... }.
In addition to those two things, the Java Memory Model (JMM) guarantees that within one thread, things will happen as if they had not been reordered. (They may actually be reordered for various reasons, including efficiency -- but not in a way that your program can notice within a single thread. For instance, if you do "x = 1; y = 2" the compiler is free to switch that such that y = 2 happens before x = 1, since a single thread can't actually notice the difference. If multiple threads are accessing x and y, then it's very possible, without proper synchronization, for another thread to see y = 2 before it sees x = 1.)
So, getting back to your original question, there are a couple interesting notes.
First, since a synchronized method is shorthand for putting the whole method inside a "synchronized (this) { ... }" block, t1's methods and t2's methods will not be synchronized against the same reference, and thus will not be synchronized relative to each other. t1's methods will only be synchronized against the t1 object, and t2's will only be synchronized against t2. In other words, it would be perfectly fine for t1.method1() and t2.method1() to run at the same time. So, of those two things the synchronized keyword provides, the first one (the exclusivity of entering the block) isn't relevant. Things could go something like:
t1 wants to enter method1. It needs to acquire the t1 monitor, which is not contended -- so it acquires it and enters the block
t2. wants to enter method2. It needs to acquire the 11 monitor, which is not contended -- s it acquires it and enters the block
t1 finishes method1 and releases its hold on the t1 monitor
t2 finishes method1 and releases its hold on the t2 monitor
As for the second thing synchronization does (establishing happens-before), making method1() and method2() synchronized will basically be ensuring that t1.method1() happens-before t1.method2(). But since both of those happen on the same thread anyway (the t1 thread), the JMM anyway guarantees that this will happen.
So it actually gets even a bit uglier. If t1 and t2 did share state -- that is, synchronization would be necessary -- then making the methods synchronized would not be enough. Remember, a synchronized method means synchronized (this) { ... }, so t1's methods would be synchronized against t1, and t2's would be against t2. You actually wouldn't be establishing any happens-before relationship between t1's methods and t2's.
Instead, you'd have to ensure that the methods are synchronized on the same reference. There are various ways to do this, but basically, it has to be a reference to an object that the two threads both know about.
Assume t1 and t2 both know about the same reference, LOCK. Both have methods like:
method1() {
synchronized(LOCK) {
// do whatever
}
}
Now things could go something like this:
t1 wants to enter method1. It needs to acquire the LOCK monitor, which is not contended -- so it acquires it and enters the block
t2 wants to enter method1. It needs to acquire the LOCK monitor, which is already held by t1 -- so t2 is put on hold.
t1 finishes method1 and releases its hold on the LOCK monitor
t2 is now able to acquire the LOCK monitor, so it does, and starts on the meat of method1
t2 finishes method1 and releases its hold on the LOCK monitor
You are saying your methods don't access global shared data and write only local variables so there is no need to synchronize them Because both the threads will be having their own copies of local variables. They will not overlap or something.
This kind of problem is faced in case of static/class variables. If multiple threads try to change the value of static variables at same time then there comes the problem so there we need to synchronize.
If the methods you're calling don't write to global shared data, you don't have to synchronize them.
In a multithreaded program, each thread has its own call stack. The local variables of each method will be separate in each thread, and will not overwrite one another.
Therefore, approach 1 works fine, does not require synchronization overhead, and is much better programming practice because it avoids duplicated code.
Thread-wise your ok. local variables within methods are not shared between threads as each instance running in a thread will have its own stack.
You won't have any speed improvements between the two approaches it is just a better organisation of the code (shorter methods are easier to understand)
If each method is independent of the other you may want to consider if they belong in the same class. If you want the performance gain create 3 different classes and execute multiple threads for each method (performance gains depends on the number of available cores cpu/io ration etc.)
Thereby: in approach(1): I need to make the methods(method1,method2
and method3) synchronized, right? in approach(2): No need to
synchronize the code sections, right?
Invoking in-lined methods v/s invoking multiple methods don't determine whether a method should be synchronized or not. I'd recommend you to read this and then ask for more clarifications.
If I'm right in both approach, using the approach(2) will give better performance, right?
At the cost of breaking down methods into a single god method? Sure, but you would be looking at a "very" miniscule improvement as compared to the lost code readability, something definitely not recommended.
method1, 2 and 3 won't be executed concurrently so if the variables that they read/write are not shared outside the class with other threads while they're running then there is no synchronization required and no need to inline.
If they modify data that other threads will read at the same time that they're running then you need to guard access to that data.
If they read data that other threads will write at the same time that they're running then you need to guard access to that data.
If other threads are expected to read data modified by method1, 2, or 3, then you need to make the run method synchronized (or them in a synchronized block) to set up a gate so that the JVM will set up a memory barrier and ensure that other threads can see the data after m1,2 and 3 are done.
Can someone please explain the difference between these two examples in the context of object locking:
public void method1(){
synchronized(this){
....
}
}
And
StringBuffer aStringBufferObject = new StringBuffer("A");
public void method2(){
synchronized(aStringBufferObject){
....
}
}
I know the first example will obtain a lock on the this instance and the second will obtain a lock of the aStringBufferObject instance. But i dont really understand what the effect or the difference of the two is.
For example, in the second example, will threads still be able to execute the code inside the synchronized block because the lock is not related to the 'this' instance?
I know that synchronizing a method or a block of code prevents multiple threads to access that block/method at the same time but what is the purpose of specifying the object to lock on and what is the difference in the way the object is specified as in the above examples?
What is the purpose of specifying the object to lock on?
Often, it is easier to synchronize on this or on the Class instance (for static methods). But, there are cases where you will need to synchronize on a specific object instead of the implicit lock (this). Such cases include:
You want to synchronize access to primitives without using this. You can only synchronize on Objects as each Object is associated with an implicit monitor in Java. Primitives do not have such implicit monitors, and therefore you need to use a lock object. Using the wrapper classes are a poor and incorrect choice, especially if you end up modifying the lock object in the guarded block.
You want to synchronize on an object that actually protects the critical section, when synchronizing on this would not offer a guarantee of thread safety. For instance, if you are synchronizing access to a ArrayList instance shared across instances of class A, then synchronizing on an instance of A is useless. A thread might create a new instance of A and gain access to the list, while another thread is modifying it. If you use a different lock that all threads must contend for then you can protect the list; this lock could be the one associated with A.class, but it could be any object that will offer the same guarantees.
You want to perform lock splitting to ensure that different guarded blocks are protected by different locks instead of the same lock. In other words, if it is thread-safe to allow different threads to acquire different locks to access different critical sections, then you can have a different lock for every critical section.
The following is an example of split lock usage:
private Object method1Lock = new Object();
private Object method2Lock = new Object();
public void method1(){
synchronized(method1Lock){
....
}
}
public void method2(){
synchronized(method2Lock){
....
}
}
You would use split locks when you can ensure that the concurrent execution of method1 and method2 do not violate the class invariants. This way, you can improve performance across threads that need access to the same object, but will be invoking different methods.
On your other question,
For example, in the second example, will threads still be able to execute the code inside the synchronized block because the lock is not related to the 'this' instance?
In the second example, any thread entering the guarded region must acquire the lock associated with aStringBufferObject. If a different thread is holding that lock, then the current thread will not proceed further. When you specify this, then the thread must acquire the lock associated with the current object. In both cases, a thread must acquire a lock; the examples are only different in the object that is being used as a lock.
Synchronizing on an object means that other blocks which synchronize on the same object will have to wait. For example:
public void methodA() {
synchronized(obj) {
//Do one job
}
}
public void methodB() {
synchronized(obj) {
//Do another job
}
}
If you call methodA() in one thread and then call methodB() in another thread, methodB() won't finish before methodA() finishes.
The synchronized block is a monitor, which leave out of details to lock and unlock a mutex. Because every object in Java has an internal lock(refer to source code of Object class), when use synchronized statement, the JVM will help you synchronize the critical section. You can also synchronize block yourself use ReentrantLock in package java.util.concurrent.locks.