I have just encountered code where synchronization was done on wrong class:
public class Test
{
public static volatile Test instance = null;
public static void setIfNull(Test newInstance)
{
synchronized (WRONG.class) // should be synchronized (Test.class)
{
if (newInstance == null)
throw new IllegalArgumentException("newInstance must not be null.");
if (instance == null) instance = newInstance;
}
}
}
Above error would not happen if whole method was synchronized:
public class Test
{
public static volatile Test instance = null;
public static synchronized void setIfNull(Test newInstance)
{
if (newInstance == null)
throw new IllegalArgumentException("newInstance must not be null.");
if (instance == null) instance = newInstance;
}
}
The way I see it, second piece of code is more error proof than first one.
Are there any pitfalls of using method synchronization over synchronization block concerning above code pattern?
Warning: In above code instance field is not properly encapsulated. Being public member nothing prevents external code not only to read it, but also write to it in thread unsafe manner. This code should not be used as proper thread safe singleton example because that is not what it is.
Are there any pitfalls of using method synchronization over synchronization block concerning above code pattern?
Since this:
public static synchronized void setIfNull(Test newInstance) {
...
}
...is exactly the same (JLS 8.4.3.6) as this:
public static void setIfNull(Test newInstance) {
synchronized (Test.class) {
...
}
}
...what you are really asking is: "What is the difference between synchronizing on some other class object WRONG.class and on This.class?".
The only thing to look out for is whether something else in your code decides to synchronize on Test.class.
1) One significant difference between synchronized method and block is that, Synchronized block generally reduce scope of lock. As scope of lock is inversely proportional to performance, its always better to lock only critical section of code. One of the best example of using synchronized block is double checked locking in Singleton pattern where instead of locking whole getInstance() method we only lock critical section of code which is used to create Singleton instance. This improves performance drastically because locking is only required one or two times.
2) Synchronized block provide granular control over lock, as you can use arbitrary any lock to provide mutual exclusion to critical section code. On the other hand synchronized method always lock either on current object represented by this keyword or class level lock, if its static synchronized method.
3) Synchronized block can throw throw java.lang.NullPointerException if expression provided to block as parameter evaluates to null, which is not the case with synchronized methods.
4) In case of synchronized method, lock is acquired by thread when it enter method and released when it leaves method, either normally or by throwing Exception. On the other hand in case of synchronized block, thread acquires lock when they enter synchronized block and release when they leave synchronized block.
Read more: http://java67.blogspot.com/2013/01/difference-between-synchronized-block-vs-method-java-example.html#ixzz3qAc5gOJy
I cant remember any pitfalls when you synchronize whole methods. Of course those are more "expensive" that just locks around certain areas.
If you're not sure i would always go for the synchronized method first until you encounter is as a bottleneck.
To avoid blocking on the wrong object simple create an instance variable:
private final Object block = new Object();
And use this when you need sychronization. Anyway when you do so, keep in mind that other methods called by different threads dont respect this and you get side effects. So you have to be careful when going this way.
I read quite some books on those topics thats an really concrete answer ist hard to mark as the correct one.
I recommend that you read "Java Concurrency in Practice" from Brian Goetz.
Also "Java Core" from Angelika Langer, Klaus Kreft (a book that goes into deep when it comes to using the volatile keyword) (German Book, still curious that no one translated this into english as it is a masterpiece in its area).
Also you could use reentant locks to get fair locking if you like.
Related
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).
One of my textbook mentions that the argument of synchronized() must be this... I know it is wrong. But I heard that since synchronized(this) is safer, one should always use it. Is that true ?
Thank you:)
No it does not have to be always this. Also it simply cannot be in the case of static methods, because there is no this.
Also it is sometimes considered wrong to synchronize to this, because then lock object is visible outside.
public class Example {
private final Object lock = new Object();
// does not compile, there is no 'this' in static context.
public static void staticMethod() {
synchronized (this) {
}
}
public void method() {
int x = 3;
//there is risk that someone else outside our code
//uses same lock
synchronized (this) {
}
//this lock is private
synchronized (lock) {
}
}
}
One of my textbook mentions that the argument of synchronized() must be this... I know it is wrong.
That is incorrect. Either the textbook is incorrect, or you have misunderstood it. The Java language allows you to synchronize on any (non-null) object reference.
But I heard that since synchronized(this) is safer, one should always use it. Is that true?
No that is not true either. It is not safer, and you certainly shouldn't always lock on this.
In fact if you are writing a general purpose library class that needs to lock "itself", it is often a good idea to declare a private lock field; e.g.
private final Object myLock = new Object();
... and lock that object rather than this. This eliminates the kind of problems that can occur is some external code decides to lock the library object for some reason, leading to unwanted contention, and possibly deadlocks between the library classes methods and the external code.
I suspect that the point that the textbook was trying to make is that all methods that are using primitive locks to give mutual exclusion and synchronization on a data structure must use the right object as the lock. This isn't necessarily the data structure object itself, but it does need to signify that object ... in some sense. (If you don't lock the object that signifies the data structure, you risk having one thread not excluding others while it uses / updates the data structure.)
Here is a sketch of the problem that private locks aim to avoid.
/** This class implements thread-safe getting / setting by synchronizing on 'this' */
public class IntHolder {
private int value;
public int getValue() {
synchronized(this) { return value; }
}
public void setValue(int value)
synchronized(this) { this.value = value; }
}
/* Somewhere else, some other code (the "external code") used a holder instance
as the lock for some larger-scale synchronization. */
IntHolder h = ...
synchronized (h) {
/* Do something that takes a long time ... */
}
The problem is that while the external code holds that lock on h, other threads won't be able to read or change the holder's value. If that was intended ... that is fine. However, if the thread-safety of the IntHolder type is intended to be "just an implementation detail" you now a potentially unexpected failure case.
IMO you're better off using 'volatile' and 'synchronized' on fields and methods if you're unsure whether synchronized(this) is a good idea in that particular place.
to put it simply, volatile places an intrinsic mutex on a variable; synchronized places an intrinsic mutex on a function call; synchronized block places an intrinsic mutex around that piece of code locked by the parameter.
Usually you'd make a lock and lock on a Object, but sometimes you want to lock on the instance itself... though, I'd advise caution on locking with a whole class instance if you only need access to one of it's members/fields (something you could've solved using synchronized and volatile in the first place)
The real reason why you might want (or not want) to lock on this is scope of the lock, you can see the lock if you lock on this. if you init a private object, the lock is hidden away.
The argument of synchronized is simply which object the hold will be placed on. It depends on what you want to do in the synchronized block that will determine what the argument should be. Using this puts a hold on the current object.
As a personal anecdote, in the project I'm currently working on, all of my synchronized holds are on COM ports, so that there's no collisions between sending and receiving packets
it doesn't matter which lock you use. Every java.lang.Object can act as a lock. You have to make sure that all operations that work on the same mutable state use the same lock.
so synchronized(this) is exactly as safe as
private final Object lock = new Object();
synchronized(lock)
If you declare a non-static method as synchronized:
public synchronized void doSomething()
{
...
}
then it is synchronized on this. So if your goal is for a synchronized block to be synchronized with synchronized non-static methods like the above, then you do need to use synchronized(this).
But you are correct: you can also write synchronized(someOtherObject), as long as you're aware that that will lock out synchronized methods of someOtherObject rather than of this.
(For static methods, by the way, synchronized synchronizes on the Class instance representing the containing class.)
No , this is not necessary that you should use this .Even you an apply lock on any other object which not an instance of this.
synchronized(obj1){
-------
}
synchronized(obj2){
-------
}
In a single method you can write something like above where you first acquire the lock on some object obj1 and then did work and released and then acquire the lock on obj2.
Aaah, the infamous Avoid synchronized(this) in Java?.
There is, actually, no difference between
public synchronized void doThis() {
}
and
public void doThis() {
synchronized (this) {
}
}
Except on the bytecode level. Both address thread-safety. They both pose a problem as you can potentially introduce deadlock, if (for example, you set a lock of the same class, within its synchronized block).
If you're worried about deadlock, then a dedicated lock should be used, like so:
public class MyClass {
private final Object lock = new Object(); //Must be final
public void doThis() {
synchronized (lock) {
}
}
}
Alternatively, use the Java java.util.concurrent.Lock interface and the java.util.concurrent.locks.ReentrantLock implementation to do basically lock..
I'm not used to working with synchronized. Does the following snippet look right?
public void setNewSessionListener(NewSessionListener newSessionListener) {
if (this.newSessionListener != null)
synchronized (this.newSessionListener) {
this.newSessionListener = newSessionListener;
}
else
this.newSessionListener = newSessionListener;
}
More specifically do I need to perform a null check? I have a gut feeling there is something fundamentally wrong with that code.
There are two mistakes. The first one is that if you access a field which requires synchronization, you always have to access it with the same lock held. Also you have to check if the field is null and write to the field in the same sychronized block, because otherwise when you write something to the field, it may already be not null.
The second one is that it is best to sychronize on something that doesn't change, in other words, on a static final field or on the instance itself. For example, you can create a lock object specifically for this purpose:
private static final Object LOCK = new Object();
And then you will write:
synchronized (LOCK) {
if (this.newSessionListener == null) this.newSessionListener = newSessionListener;
}
Your feeling is right. You should do the null check inside the synchronized block. Otherwise the block won't prevent double initialization. Furthermore, you shouldn't synchronize on this.newSessionListener which you are about to change - choose an object (reference) which is going to stay around for the whole scope of the block. This is the only way to guarantee that only one thread can enter this block of code at any point in time. The typical way to achieve this is to synchronize on this. Alternatively, you may synchronize on a private final object, kept for this sole purpose.
Moreover, ultimately you are performing the same assignment in both the if and the else branches, which is probably not what you want.
This is, at a minimum, a very bad idea. You are synchronizing on an object you then assign to.
Because you are using synchronized I assume this is called asynchronously and it could be called by one thread while another thread is inside this code. If so, you are not locking on a common object, you are locking on the value it is holding at that point in time.
Probably, and I stress probably, you can do synchronized (this). That will insure that all calls to this method for this specific object are synchronized. And that calls to other instances of this class are locked for that other object - but not across instances.
If you want to synchronize across all instantiated objects, call synchronized (YourClass)
Here's another possibility (i tend to prefer explicit locks over the synchronized block):
private ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
// do your synchronized code here.
}
finally {
lock.unlock();
}
Though just by looking at your code, i'm not sure why there's even an if block. Why are you synchronized in one case, and not the other? Especially considering you're making the same assignment in either case?
I saw some examples in java where they do synchronization on a block of code to change some variable while that variable was declared volatile originally .. I saw that in an example of singleton class where they declared the unique instance as volatile and they sychronized the block that initializes that instance ... My question is why we declare it volatile while we synch on it, why we need to do both?? isn't one of them is sufficient for the other ??
public class SomeClass {
volatile static Object uniqueInstance = null;
public static Object getInstance() {
if (uniqueInstance == null) {
synchronized (someClass.class) {
if (uniqueInstance == null) {
uniqueInstance = new SomeClass();
}
}
}
return uniqueInstance;
}
}
thanks in advance.
Synchronization by itself would be enough in this case if the first check was within synchronized block (but it's not and one thread might not see changes performed by another if the variable were not volatile). Volatile alone would not be enough because you need to perform more than one operation atomically. But beware! What you have here is so-called double-checked locking - a common idiom, which unfortunately does not work reliably. I think this has changed since Java 1.6, but still this kind of code may be risky.
EDIT: when the variable is volatile, this code works correctly since JDK 5 (not 6 as I wrote earlier), but it will not work as expected under JDK 1.4 or earlier.
This uses the double checked locking, note that the if(uniqueInstance == null) is not within the synchronized part.
If uniqueInstance is not volatile, it might be "initialized" with a partially constructed object where parts of it isn't visible to other than the thread executing in the synchronized block. volatile makes this an all or nothing operation in this case.
If you didn't have the synchronized block, you could end up with 2 threads getting to this point at the same time.
if(uniqueInstance == null) {
uniqueInstance = new someClass(); <---- here
And you construct 2 SomeClass objects, which defeats the purpose.
Strictly speaking, you don't need volatile , the method could have been
public static someClass getInstance() {
synchronized(FullDictionary.class) {
if(uniqueInstance == null) {
uniqueInstance = new someClass();
}
return uniqueInstance;
}
}
But that incurs the synchronization and serialization of every thread that performs getInstance().
This post explains the idea behind volatile.
It is also addressed in the seminal work, Java Concurrency in Practice.
The main idea is that concurrency not only involves protection of shared state but also the visibility of that state between threads: this is where volatile comes in. (This larger contract is defined by the Java Memory Model.)
You can do synchronization without using synchronized block.
It's not a necessary to use volatile variable in it...
volatile updates the one variable from main memory..and
synchronized Update all shared variables that have been accessed from main memory..
So you can use it according to your requirement..
My two cents here
Frist a quick explanation of the intuition of this code
if(uniqueInstance == null) {
synchronized(someClass.class) {
if(uniqueInstance == null) {
uniqueInstance = new someClass();
}
}
}
The reason it checks uniqueInstance == null twice is to reduce the overhead of calling the synchronized block which is relatively slower. So called double-checked locking.
Second, the reason it uses synchronized is easy to understand, it make the two operations inside the synchronized block atomic.
Last the volatile modifier makes sure all threads see the same copy so the very first check outside of the synchronized block will see the value of uniqueInstance in a way which is "synchronized"
with the synchronized block. Without the volatile modifier one thread can assign a value to uniqueInstance but the other thread may not see it by the first check. (Although the second check will see it)
I know the difference between synchronized method and synchronized block but I am not sure about the synchronized block part.
Assuming I have this code
class Test {
private int x=0;
private Object lockObject = new Object();
public void incBlock() {
synchronized(lockObject) {
x++;
}
System.out.println("x="+x);
}
public void incThis() { // same as synchronized method
synchronized(this) {
x++;
}
System.out.println("x="+x);
}
}
In this case what is the difference between using lockObject and using this as the lock? It seems to be the same to me..
When you decide to use synchronized block, how do you decide which object to be the lock?
Personally I almost never lock on "this". I usually lock on a privately held reference which I know that no other code is going to lock on. If you lock on "this" then any other code which knows about your object might choose to lock on it. While it's unlikely to happen, it certainly could do - and could cause deadlocks, or just excessive locking.
There's nothing particularly magical about what you lock on - you can think of it as a token, effectively. Anyone locking with the same token will be trying to acquire the same lock. Unless you want other code to be able to acquire the same lock, use a private variable. I'd also encourage you to make the variable final - I can't remember a situation where I've ever wanted to change a lock variable over the lifetime of an object.
I had this same question when I was reading Java Concurrency In Practice, and I thought I'd add some added perspective on the answers provided by Jon Skeet and spullara.
Here's some example code which will block even the "quick" setValue(int)/getValue() methods while the doStuff(ValueHolder) method executes.
public class ValueHolder {
private int value = 0;
public synchronized void setValue(int v) {
// Or could use a sychronized(this) block...
this.value = 0;
}
public synchronized int getValue() {
return this.value;
}
}
public class MaliciousClass {
public void doStuff(ValueHolder holder) {
synchronized(holder) {
// Do something "expensive" so setter/getter calls are blocked
}
}
}
The downside of using this for synchronization is other classes can synchronize on a reference to your class (not via this, of course). Malicious or unintentional use of the synchronized keyword while locking on your object's reference can cause your class to behave poorly under concurrent usage, as an external class can effectively block your this-synchronized methods and there is nothing you can do (in your class) to prohibit this at runtime. To avoid this potential pitfall, you would synchronize on a private final Object or use the Lock interface in java.util.concurrent.locks.
For this simple example, you could alternately use an AtomicInteger rather than synchronizing the setter/getter.
Item 67 of Effective Java Second Edition is Avoid excessive synchronization, thus I would synchronize on a private lock object.
Every object in Java can act as a monitor. Choosing one is dependent on what granularity you want. Choosing 'this' has the advantage and disadvantage that other classes could also synchronize on the same monitor. My advice though is to avoid using the synchronize keyword directly and instead use constructs from the java.util.concurrency library which are higher level and have well defined semantics. This book has a lot of great advice in it from very notable experts:
Java Concurrency in Practice
http://amzn.com/0321349601
In this case it does not matter which object you choose for lock. But you must consistently use the same object for locking to achieve correct synchronization. Above code does not ensure proper synchronization as you once use the 'this' object as lock and next the 'lockObject' as lock.