Is there any good use case favouring implicit locks by synchronized keyword ?
Generally the thing to consider is that synchronized lock on this (either the instance of class depending on if it is a static method). This means that if another class has access to the instance that has the synchronized it could lock on the same object.
Therefore it is generally considered best practice to explicitly synchronize / lock on a private final field.
If you don't need the tryLock, lockInterruptibly or any other specialised methods that are available through lock objects, then using synchronized is safer and easier to use: when using a Lock, you need to follow a specific unlocking pattern with a finally block and failure to do so could end up in a lock that never gets released.
If you do need those methods then you don't have a choice...
Related
Let's say I have an EntityPool. After I get an entity from the pool, I need to modify the entity in a thread-safe way. So I see 2 choices:
1) Using synchronized:
Entity e = pool.getById(id);
synchronized (e) {
// modifying e
}
2) Add a lock to the Entity class and use it:
Entity e = pool.getById(id);
Lock l = e.getLock();
try {
l.lock();
// modifying e
} finally {
l.unlock();
}
I've heard that I should avoid using "synchronized" keyword. Should I use lock instead? But it seems weird to me that the Entity class should know anything about synchronization.
There are different use cases to justify both approaches.
1 is common. It uses the object itself as a lock, so any synchronized methods on the entity as well as any other synchronized access are serialized. It also does not require making the Entity class lock-aware.
2 requires that you embed a lock into the entity class. This allows you to control synchronization in a more fine-grained manner. You can, for instance, use the lock to control access to a subset of the object state while keeping methods accessing other parts of the object lock-free.
If you know what you're doing, there's no need to avoid the synchronized keyword. That can be said for locks as well.
Use 'synchronized' if your usage follows lexical scope. Synchronization starts when you enter a synchronized method or the body of a synchronized {…} clause, and ends when you leave it.
By contrast, locking and unlocking can be applied to arbitrary sequences of actions. You can, for example, acquire the lock in a call to some sort of 'startSomething' method, and release the lock in a later call to an 'endSomething' method. The cost of this is your need to ensure correctness.
tl;dr - use synchronized unless it clearly doesn't work for your use case.
I gone through the article "http://www.ibm.com/developerworks/java/library/j-jtp10264/".They mentioned that "The Lock framework is a compatible replacement for synchronisation". I understood that by using Reentrant locks we can hold the lock across the methods, wait for the lock for certain period of time (It is not possible using synchronised block (or) methods). My doubt is, is it possible to replace the application with synchronisation mechanism with Reentrant locks?
For example, I want to implement a thread safe stack data structure, where all the push, pop, getTop methods are synchronised, so in multi threaded environment, only one thread can able to access one synchronised method at a time (If one thread is using push method, no other threads can able to access push, pop, getTop (or) any other synchronised methods of Stack class). Is it possible to implement same thread safe stack data structure using Reentrant lock? If possible, please provide an example to understand this.
Anything you can do with synchronized you can also do with ReentrantLock but not vice-versa. That being said, if all you need are lock/unlock semantics I would suggest synchronized as it's, in my opinion, more readable.
The answer is "Yes".
lock - unlock pair used instead of synchronize( ) { ... }.
await and signal in Condition is replacement for wait and notify.
Brian Goetz discusses this in "Java Concurrency in Practice" in chapter 13.4:
ReentrantLock is an advanced tool for situations where intrinsic locking is not practical. Use it if you need its advanced features: timed, polled, or interruptible lock acquisition, fair queueing, or non-block-structured locking. Otherwise, prefer synchronized.
I absolutely agree because IMHO this:
synchronized (lock) {
// ...
}
Is way more readable and less error prone than this:
try {
lock.lock();
// ...
} finally {
lock.unlock();
}
Long story short: from a technical point of view, yes, you could replace synchronized with ReentrantLock, but I wouldn't do it per se.
Also checkout these questions:
Synchronization vs Lock
Why use a ReentrantLock if one can use synchronized(this)?
ReentrantLock is one of the alternatives to synchronization.
A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.
Refer to this question for other alternatives to synchronization (Concurrent Collections, Atomic variables, Executors, ThreadLocal variables):
Avoid synchronized(this) in Java?
If I call a object synchronized, can I access objects inside that object as if they were synchronized? Or can I only access the data types?
Even though your goal is to protect data, synchronization provides exclusivity around a block of code, not a piece of data. Code outside the synchronization blocks (or in blocks that use different objects), may alter the data you are trying to protect even if that isn't what you want.
Any correct locking strategy must ensure that blocks of code that could interfere with each other hold the same lock. That includes code which could interfere with another copy of itself run in a second thread.
synchronized (myObject) {
// sensitive code
}
Locking at the method level is just a shorthand for locking the this pointer for the body of the method. (Or the class object for a static method).
Possibly, but only with care. You can do this if you always lock the same object.
Most likely you have to lock each object.
The ability to synchronize on every object is a commonly cited annoyance in Java because it's confusing.
Basically, all it means is that every object can be a lock. That's it. Hence, there is no special effect on object's members when you lock on the parent object and it doesn't matter which particular object you use as a lock. If all your thread locks on the same object, only one of them will be running/accessing whatever code is in the synchronized block. If some of them don't, there is no such guarantee.
If you want to make sure only one thread is accessing a member at any given time, make sure all threads that access that member lock (or "synchronize") on the same object before accessing it. As long as you do that, it doesn't matter which object you use for the lock.
I have a little difficulty in understanding the concept of private locks:
public class MyObject {
private final Object lock = new Object(); // private final lock object
public void mymethod() {
synchronized (lock) { // Locks on the private Object
// ...
}
}
}
In the code above, lock is acquired on a different object but the code in the current object is guarded by synchronised block. Now, apart from the lock object in the code above, it could be any other object too. I find it difficult to understand how the lock on another object is related to the synchronised keyword in the current object. IMO, it may lead to some malicious code to lock any object. What is the basis of allowing locks on other objects.
Well you could, for example, have an object that manages two lists.
If its possible for thread A to alter list 1 while thread B alters list 2 then you'd use distinct locks, rather than synchronizing on the owning object.
Essentially explicit locks allow for finer grained control of behavior.
IMO, it may lead to some malicious code to lock any object.
This is the crux of the issue, actually.
With a separate lock object as shown (crucially, with private access) then only code in the MyObject class will be able to acquire a lock on that monitor - so you can see all of the code that might take part in locking situations involving this class.
Going to the other extreme, if you acquire a lock on e.g. a constant String, then any code, anywhere in the same JVM that locks on the same String will contend with your class - which is almost certainly not intended and will be very hard to track down.
Basically - if you lock on a non-private object, that then becomes part of your public interface, effectively. Sometimes this is intended (e.g. for the Collections.synchronizedFoo objects, they declare that one can synchronize on the object itself in order to coarsen your lock). Often it is not and is merely an oversight.
You should keep your lock monitors private, for the same reason you keep private member variables private - to prevent other code messing with things that they shouldn't. And this is basically never private.
You're right, the code you provided could lock on any object. However, it didn't. It locked on a private instance field--a field which only that instance can access. That means that no other code can possibly lock on that object. You didn't, in this case, lock on some other object because if some other code locked on it, then you'd have to wait for it (and it may never be released).
"Malicious" code could lock on any object, but it only hurts other code if that other code attempts to lock on the same object. My creating your own private object to lock on, you protect yourself from locks by other code.
synchronized is actually effective for multithreaded environment. This method is to allow concurrency in your system.
When an object is synchronized, the first thread that "touched" the object puts a lock on that object until that thread that is using the locked object finished using the object and releases it. It prevents many threads to change the same object concurrently.
Locks are always on objects.
purpose of syncronized block is to guard objects (one associated with block) with locks, So this means only thread which has lock for object can enter this block.
There is nothing wrong with it, There can be situation in code where you don't need to synchronize complete method but just few lines of code.
One use of synchronization block is in situation when state of object (and other objects related to it) needs to changed in multi threaded env, But the Class of this object doesn't have synchronized methods to alter state of object.
In such situation synchronization is achieved using such block.
Locks should be private iff there will be no reason for any lock related to your class to be held while no thread is actually running code in your class (or code called from code in your class). If you need to e.g. allow someone to maintain exclusive control over your object between operations, you'll have to expose a lock. This opens up many potential issues, including deadlock, so it's generally best if you can design your interfaces and contracts so as to render such extended locking unnecessary.
BTW, note that performing callbacks while holding a lock is slightly less dangerous than exposing a lock, but only slightly. You would eliminate the danger that a caller might acquire a lock and simply forget about it, but the danger of deadlock would still remain.
From Sun's tutorial:
Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. (An important exception: final fields, which cannot be modified after the object is constructed, can be safely read through non-synchronized methods, once the object is constructed) This strategy is effective, but can present problems with liveness, as we'll see later in this lesson.
Q1. Is the above statements mean that if an object of a class is going to be shared among multiple threads, then all instance methods of that class (except getters of final fields) should be made synchronized, since instance methods process instance variables?
In order to understand concurrency in Java, I recommend the invaluable Java Concurrency in Practice.
In response to your specific question, although synchronizing all methods is a quick-and-dirty way to accomplish thread safety, it does not scale well at all. Consider the much maligned Vector class. Every method is synchronized, and it works terribly, because iteration is still not thread safe.
No. It means that synchronized methods are a way to achieve thread safety, but they're not the only way and, by themselves, they don't guarantee complete safety in all situations.
Not necessarily. You can synchronize (e.g. place a lock on dedicated object) part of the method where you access object's variables, for example. In other cases, you may delegate job to some inner object(s) which already handles synchronization issues.
There are lots of choices, it all depends on the algorithm you're implementing. Although, 'synchronized' keywords is usually the simplest one.
edit
There is no comprehensive tutorial on that, each situation is unique. Learning it is like learning a foreign language: never ends :)
But there are certainly helpful resources. In particular, there is a series of interesting articles on Heinz Kabutz's website.
http://www.javaspecialists.eu/archive/Issue152.html
(see the full list on the page)
If other people have any links I'd be interested to see also. I find the whole topic to be quite confusing (and, probably, most difficult part of core java), especially since new concurrency mechanisms were introduced in java 5.
Have fun!
In the most general form yes.
Immutable objects need not be synchronized.
Also, you can use individual monitors/locks for the mutable instance variables (or groups there of) which will help with liveliness. As well as only synchronize the portions where data is changed, rather than the entire method.
synchronized methodName vs synchronized( object )
That's correct, and is one alternative. I think it would be more efficient to synchronize access to that object only instead synchronize all it's methods.
While the difference may be subtle, it would be useful if you use that same object in a single thread
ie ( using synchronized keyword on the method )
class SomeClass {
private int clickCount = 0;
public synchronized void click(){
clickCount++;
}
}
When a class is defined like this, only one thread at a time may invoke the click method.
What happens if this method is invoked too frequently in a single threaded app? You'll spend some extra time checking if that thread can get the object lock when it is not needed.
class Main {
public static void main( String [] args ) {
SomeClass someObject = new SomeClass();
for( int i = 0 ; i < Integer.MAX_VALUE ; i++ ) {
someObject.click();
}
}
}
In this case, the check to see if the thread can lock the object will be invoked unnecessarily Integer.MAX_VALUE ( 2 147 483 647 ) times.
So removing the synchronized keyword in this situation will run much faster.
So, how would you do that in a multithread application?
You just synchronize the object:
synchronized ( someObject ) {
someObject.click();
}
Vector vs ArrayList
As an additional note, this usage ( syncrhonized methodName vs. syncrhonized( object ) ) is, by the way, one of the reasons why java.util.Vector is now replaced by java.util.ArrayList. Many of the Vector methods are synchronized.
Most of the times a list is used in a single threaded app or piece of code ( ie code inside jsp/servlets is executed in a single thread ), and the extra synchronization of Vector doesn't help to performance.
Same goes for Hashtable being replaced by HashMap
In fact getters a should be synchronized too or fields are to be made volatile. That is because when you get some value, you're probably interested in a most recent version of the value. You see, synchronized block semantics provides not only atomicity of execution (e.g. it guarantees that only one thread executes this block at one time), but also a visibility. It means that when thread enters synchronized block it invalidates its local cache and when it goes out it dumps any variables that have been modified back to main memory. volatile variables has the same visibility semantics.
No. Even getters have to be synchronized, except when they access only final fields. The reason is, that, for example, when accessing a long value, there is a tiny change that another thread currently writes it, and you read it while just the first 4 bytes have been written while the other 4 bytes remain the old value.
Yes, that's correct. All methods that modify data or access data that may be modified by a different thread need to be synchronized on the same monitor.
The easy way is to mark the methods as synchronized. If these are long-running methods, you may want to only synchronize that parts that the the reading/writing. In this case you would definie the monitor, along with wait() and notify().
The simple answer is yes.
If an object of the class is going to be shared by multiple threads, you need to syncronize the getters and setters to prevent data inconsistency.
If all the threads would have seperate copy of object, then there is no need to syncronize the methods. If your instance methods are more than mere set and get, you must analyze the threat of threads waiting for a long running getter/setter to finish.
You could use synchronized methods, synchronized blocks, concurrency tools such as Semaphore or if you really want to get down and dirty you could use Atomic References. Other options include declaring member variables as volatile and using classes like AtomicInteger instead of Integer.
It all depends on the situation, but there are a wide range of concurrency tools available - these are just some of them.
Synchronization can result in hold-wait deadlock where two threads each have the lock of an object, and are trying to acquire the lock of the other thread's object.
Synchronization must also be global for a class, and an easy mistake to make is to forget to synchronize a method. When a thread holds the lock for an object, other threads can still access non synchronized methods of that object.