synchronized(this) blocks whole object? [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
synchronized block vs synchronized method?
From accepted answer to this question: In Java critical sections, what should I synchronize on?
I learn that
public synchronized void foo() {
// do something thread-safe
}
and:
public void foo() {
synchronized (this) {
// do something thread-safe
}
}
do exactly the same thing. But in first case we make synchronized only one method of object, and in second case we make inaccessible Whole object. So why this two code snippests do same things?

You seem to be mixing things.
Firstly
public synchronized void method() {
}
is equivalent, from a synchronization perspective, to:
public void method() {
synchronized (this) {
}
}
The pros / cons have already been mentioned and the various duplicates give more information.
Secondly,
synchronized(someObject) {
//some instructions
}
means that the instructions in the synchronized block can't be executed simultaneously by 2 threads because they need to acquire the monitor on someObject to do so. (That assumes that someObject is a final reference that does not change).
In your case, someObject happens to be this.
Any code in your object that is not synchronized, can still be executed concurrently, even if the monitor on this is held by a thread because it is running the synchronized block. In other words, synchronized(this) does NOT "lock the whole object". It only prevents 2 threads from executing the synchronized block at the same time.
Finally, if you have two synchronized methods (both using this as a lock), if one thread (T1) acquires a lock on this to execute one of those 2 methods, no other thread is allowed to execute any of the two methods, because they would need to acquire the lock on this, which is already held by T1.
That situation can create contention in critical sections, in which case a more fine grained locking strategy must be used (for example, using multiple locks).

We don't synchronize an object, instead we synchronize a block of code. In the first that block of code is the method itself, while in the second it's the synchronized block.
The object only provides the lock so as to prevent multiple threads from simultaneously entering that block of code. In the first case, the this object (the one on which the method is invoked) will be used implicitly as the lock, while in the second case it doesn't always have to be this object, it could be some other object also.

They do the same thing. The first form is a short-hand for the second form.
One minor difference between the two constructs is this - synchronized blocks are compiled into monitorenter (op-code 0xC2) and monitorexit (op-code 0xC3) instructions.
A synchronized method, when compiled, is distinguished in the runtime constant pool by
the ACC_SYNCHRONIZED flag, which is checked by JVM’s the method invocation instructions. This difference does not have much significance in practice though.

They dont do same things. First part being synched from beginning to end. Second is just synching the block(not whole method). Second one has some flexibility.

Related

what is this piece of code doing [duplicate]

This question already has answers here:
What does 'synchronized' mean?
(17 answers)
Closed 6 years ago.
public int synchronizedBlockGet() {
synchronized( this ) {
return i;
}
}
I have come across this code while reading some article. what is synchronized ? a class , or method or interface ? Please explain.
Synchronized or in general synchronization come when you are dealing with threads. For example, let's say there are 2 threads in you program. Both of these threads are using the same object. (Consider a scenario where one thread is writing to an ArrayList and the other one is reading from it). It those cases, we have to ensure that the other thread don't do a read or a write while a thread is writing to the list. This is because, a write to a list will consist of at least 3 steps
read from memory
modify the object(list)
write back to the memory.
In order to make sure that these threads don't intercept and will not cause inconsistencies, we use the concept of thread synchronization.
There are several ways of achieving synchronization including synchronized methods and synchronized blocks. The code you have provided is a synchronized block.
public int synchronizedBlockGet() {
synchronized( this ) {
return i;
}
}
Here what happens is, once a thread is inside the synchronizedBlockGet method, it will lock the entire object(called acquiring the lock of the object) where the above method is.
synchronized(this) means that the current thread will lock the entire object. No other thread can therefore access this object until the current thread leave the synchronized block and release the object. Even though the example you have given is not a necessary situation of synchronization, the thing that happens behind is the same.
Its a keyword and it will allow only single thread at a time to enter into the block.
It will achieve this by acquiring lock on this object.

Java synchronized method

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.

Java Threading - Synchronized code

Why do you have to specify, which object has locked a synchronized block of code?
You don't have to specify which object has locked a synchronized method as it is always locked by 'this' (I believe).
I have two questions:
Why can't you block a none static method with an object other than
'this' ?
Why do you have to specify the object that has blocked
synchronized code?
I have read chapter nine of SCJP for Java 6, but I am still not clear on this.
I realize it is probably a basic question, but I am new to Threading.
Why can't you block a none static method with an object other than 'this' ?
You can:
public void foo() {
synchronized (lock) {
...
}
}
Why do you have to specify the object that has blocked synchronized code?
Because that's how the language designers chose to design the language. synchronized, when used on instance methods, implicitely uses this as the lock. synchronized when used on a block must explicitely specify the lock.
You can.
The code
synchronized foo() {
// some stuff
}
Is logically equal to code
foo() {
synchronized(this) {
// some stuff
}
}
I said "logically" because these 2 examples generate different byte code.
If method foo() is static synchronization is done of class object.
However you can wish to create several synchronized blocks that are synchronized on different objects into one class or even into one method. In this case you can use synchronized (lock) where lock is not this:
foo() {
synchronized(one) {}
///..........
synchronized(two) {}
}
You can specify any object you want which should have the lock on the synchronized code block. Actually, you shouldn't use synchronize(this) at all (or maybe be careful about it, see Avoid synchronized(this) in Java?).
EVERY object has a lock on which you can synchronize:
final Object lock = new Object()
synchronized ( lock ) { ... }
If you want to synchronize the whole method, you cannot say on which object, so it is always "this" object.
synchronized foo() {....}
The first way of locking is better, by the way.
It is not recommended to lock each method with this as it reduces the concurrency in most cases. So it is recommended to use Lock Stripping in which only the specific part of the code that needs to be protected is kept in synchronized block.
It is a practice that is explained well in Java Concurrency in Practice. But note this book is useful only when you have some basic experience with threading.
Some nuggets to keep in mind:
Do not overuse synchronization
use method level synchronization only when the whole method needs to be protected
Use different locks to protect two unrelated entities, which will increase the chances of concurrency. or else for reading or writing two unrelated entities threads will block on same lock.
public void incrementCounter1(){
synchronized(lockForCounter1){
counter1++;
}
}
public void incrementCounter2(){
synchronized(lockForCounter2){
counter2++;
}
}
I think your two questions actually are same. let's say if you wanna synchronized a method m of object a between multiple threads, you need a common base system or channel that threads can talk to, this is actually what object lock offers, so when you wanna a method of a object be synchronized there is no need for another object lock to do this, because the object you access itself has this lock, that's how and why lanuage designed.
while synchronized a block is not the same thing, threads can have different talking base other than this object itself, for instance, you can set a same object as synchronized object lock for synchronized block, so all objects of this Class can be synchronized at that block!
From the concurrency tutorial, the Synchronized methods part:
To make a method synchronized, simply add the synchronized keyword to its declaration:
public class SynchronizedCounter {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
}
If count is an instance of SynchronizedCounter, then making these methods synchronized has two effects:
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.
Simply put, that's how synchronization in Java works.
You don't have to specify which object has locked a synchronized method as it is always locked by 'this' (I believe).
True for instance methods, for static methods it locks upon the class object.
Why can't you block a none static method with an object other than 'this' ?
Note that:
public synchronized void increment() {
c++;
}
is equivalent in behavior to:
public void increment() {
synchronized(this) {
c++;
}
}
In this code snippet you can replace this with any object you wish.
Why do you have to specify the object that has blocked synchronized code?
Some, let's call it critical, block of code is to be ran only sequentially, but in uncontrolled concurrent environment it is possible that it will be ran in parallel. That's why synchronization mechanisms exists.
So we can divide the code like this:
the code safe to be ran in parallel (default situation)
the code that has to be synchronized (must be marked somehow)
That markation is made via the synchronized keyword and the corresponding lock object.
If you have two different critical code blocks that must not be ran together, they'll both have the synchronized keyword, and let's say they have the same lock object.
While the first block is executing, the lock object becomes "locked". If during that time the second block needs to get executed, the first command of that code block is:
synchronized(lock) {
but that lock object is in locked state because the first block is executing. The execution of the second block halts on that statement until the first block finishes the execution, and unlocks the state of the lock object. Then the second block may proceed with the execution (and lock the lock object again).
That mechanism is called the mutual exclusion and the lock is a general concept not tied to the Java programming language.
The details of the "lock object locking" process can be found here.
You can lock with any instance of an object but programmers usually
use this or locker...
Because it restrict access to that part of code by other threads
(unit of code processing) so you make sure whole of that part run in
consistence and nothing (i.e. a variable) would be alerted by another thread.
Consider:
a = 1;
a++;
Thread one reaches second line and you expect a = 2 but another thread executes first line and instead of 2 you have a = 1 for first thread and a = 2 for second thread. Now:
synchronized (whatever)
{
a = 1;
a++;
}
Now second thread would be blocked from entering into the code block (synchronized body) until first one leaves it (release the lock).

Do I need to synchronize methods inside the run method in java when calling start method?

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.

Is 'synchronized' really just syntactic sugar?

I am new to multithreading, and I wrote this code which prints the numbers 1-10000 by having concurrently running threads increment and print a variable.
Here's the code I'm using:
package threadtest;
public class Main{
static int i=0;
static Object lock=new Object();
private static class Incrementer extends Thread{
#Override
public void run(){
while (true){
synchronized(lock){
if (i>=10000)
break;
i++;
System.out.println(i);
}
}
}
}
public static void main(String[] args) {
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
}
}
This works - I wrote up a test program to check the output, and the numbers printed are exactly 1-10000 in order.
My question is this: I've heard that synchronized is only syntactic sugar. But I can't seem to achieve a successful result without using it. What am I missing?
synchronized is by no means syntactic sugar for anything. There is no way to work locks in Java without using the synchronized keyword.
Where there is "syntactic sugar" of a sort in locks in Java is that synchronized can apply both to blocks (as you've done it above) and to whole methods. The following two methods are roughly equivalent in semantics:
synchronized void method1() {
// ... do stuff ...
}
void method2() {
synchronized(this) {
// ... do stuff ...
}
}
So why would you want to do the second version instead of the first?
Synchronized method invocations are far slower than plain old method invocations, like by about an order of magnitude. If your synchronized code isn't guaranteed to always execute (say it's in a conditional), then you probably don't want to synchronize the whole method.
Synchronized methods hold locks for longer than synchronized blocks (because of all the method setup/tear down code). The second method above will hold the lock for less time because the time spent setting up and tearing down the stack frame won't be locked.
You can have much finer control over exactly what you're locking if you go with the synchronized blocks.
(Courtesy of starblue) Synchronized blocks can use objects other than this for locking which gives you more flexible locking semantics.
It sounds like your sources are just wrong. The syncrhonized keyword is important to use - and use properly - when writing thread-safe code. And it sounds like your own experiments bear this out.
For more on synchronization in Java:
Java Synchronized Methods
Java Locks and Synchronized Statements
Actually as of Java 5 you (formally) have an alternative set of tools in java.util.concurrent. See here for more details. As detailed in the article the monitor locking model provided at Java's language level has a number of significant limitations and can be difficult to reason about when there are a complex set of interdependent objects and locking relationships making live-lock a real possibility. The java.util.concurrent library offers locking semantics which might be more familiar to programmers who've had experience in POSIX-like systems
Of course, "synchronized" is just syntactic sugar - extremley useful syntactic sugar.
If you want sugar-free java programs, you should be writing directly in java byte code the monitorenter, monitorexit, lock, and unlock operations referenced in VM Specifications 8.13 Locks and Synchronization
There is a lock associated with every object. The Java programming
language does not provide a way to
perform separate lock and unlock
operations; instead, they are
implicitly performed by high-level
constructs that always arrange to pair
such operations correctly. (The Java
virtual machine, however, provides
separate monitorenter and monitorexit
instructions that implement the lock
and unlock operations.)
The synchronized statement computes a
reference to an object; it then
attempts to perform a lock operation
on that object and does not proceed
further until the lock operation has
successfully completed. (A lock
operation may be delayed because the
rules about locks can prevent the main
memory from participating until some
other thread is ready to perform one
or more unlock operations.) After the
lock operation has been performed, the
body of the synchronized statement is
executed. Normally, a compiler for the
Java programming language ensures that
the lock operation implemented by a
monitorenter instruction executed
prior to the execution of the body of
the synchronized statement is matched
by an unlock operation implemented by
a monitorexit instruction whenever the
synchronized statement completes,
whether completion is normal or
abrupt.
A synchronized method automatically
performs a lock operation when it is
invoked; its body is not executed
until the lock operation has
successfully completed. If the method
is an instance method, it locks the
lock associated with the instance for
which it was invoked (that is, the
object that will be known as this
during execution of the method's
body). If the method is static, it
locks the lock associated with the
Class object that represents the class
in which the method is defined. If
execution of the method's body is ever
completed, either normally or
abruptly, an unlock operation is
automatically performed on that same
lock.
Best practice is that if a variable is
ever to be assigned by one thread and
used or assigned by another, then all
accesses to that variable should be
enclosed in synchronized methods or
synchronized statements.
Although a compiler for the Java
programming language normally
guarantees structured use of locks
(see Section 7.14, "Synchronization"),
there is no assurance that all code
submitted to the Java virtual machine
will obey this property.
Implementations of the Java virtual
machine are permitted but not required
to enforce both of the following two
rules guaranteeing structured locking.
Let T be a thread and L be a lock.
Then:
The number of lock operations performed by T on L during a method
invocation must equal the number of
unlock operations performed by T on L
during the method invocation whether
the method invocation completes
normally or abruptly.
At no point during a method invocation may the number of unlock
operations performed by T on L since
the method invocation exceed the
number of lock operations performed by
T on L since the method invocation.
In less formal terms, during a method
invocation every unlock operation on L
must match some preceding lock
operation on L.
Note that the locking and unlocking
automatically performed by the Java
virtual machine when invoking a
synchronized method are considered to
occur during the calling method's
invocation.
Synchronization is one of the most important concepts while programming in multi thread environment.
While using synchronization one has to consider the object over which synchronization takes place.
For example if a static method is to be synchronized then the synchronization must be on the class level using
synchronized(MyClass.class){
//code to be executed in the static context
}
if the block in instance method is to be synchronized then the synchronization must be using an instance of an object which is shared between all the threads.
Most poeple go wrong with the second point as it appears in your code where the synchronization appears to be on different objects rather than a single object.

Categories

Resources