Why are the methods in the Observable class are synchronized?
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
Observable is intended to be a very thread-safe class; it manipulates shared data 'atomically', meaning that only one thread can access it at a time. The synchronized keyword forces each interacting thread to access the Observable instance's data atomically.
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.
Note that some methods, such as notifyObservers(), are not synchronized. This is because they do not directly affect the instance data of the Observable.
Read this writeup if you want to learn more about thread-safety.
I can't give you a definitive answer regarding why Observable is implemented the way it is, but I can explain the effect.
While Vector is a synchronized collection, it isn't synchronized while iterating. This is similar to the wrappers returned by the Collections.synchronizedXXX methods. In order to safely iterate a Vector in a concurrent context you need external synchronization. They accomplish this by using synchronized methods. But if you look at notifyObservers you'll see that the method isn't synchronized. However, if you look at the body of notifyObservers you'll see a synchronized(this) {} block. They do it this way because only part of the method body needs to be executed while holding the lock. If you're not aware, a synchronized instance method is the same as using synchronized(this) {} for the whole method.
The other effect caused by using synchronized methods is that both the obs field and the changed field are guarded by the same lock. This keeps the state between those two fields consistent in a multi-threaded environment. Why they chose the enclosing instance as the lock, I have no idea, but that's what they did.
Note that, as near as I can tell, the Observable class gives no guarantees regarding thread-safety in its documentation. This means the fact that it is thread-safe is an implementation detail.
Also note that Observable has been deprecated since Java 9.
Related
I'm working with a framework that requires a callback when sending a request. Each callback has to implement this interface. The methods in the callback are invoked asynchronously.
public interface ClientCallback<RESP extends Response>
{
public void onSuccessResponse(RESP resp);
public void onFailureResponse(FailureResponse failure);
public void onError(Throwable e);
}
To write integration tests with TestNG, I wanted to have a blocking callback. So I used a CountDownLatch to synchronize between threads.
Is the AtomicReference really needed here or is a raw reference okay? I know that if I use a raw reference and a raw integer (instead of CountDownLatch), the code wouldn't work because visibility is not guaranteed. But since the CountDownLatch is already synchronized, I wasn't sure whether I needed the extra synchronization from AtomicReference.
Note: The Result class is immutable.
public class BlockingCallback<RESP extends Response> implements ClientCallback<RESP>
{
private final AtomicReference<Result<RESP>> _result = new AtomicReference<Result<RESP>>();
private final CountDownLatch _latch = new CountDownLatch(1);
public void onSuccessResponse(RESP resp)
{
_result.set(new Result<RESP>(resp, null, null));
_latch.countDown();
}
public void onFailureResponse(FailureResponse failure)
{
_result.set(new Result<RESP>(null, failure, null));
_latch.countDown();
}
public void onError(Throwable e)
{
_result.set(new Result<RESP>(null, null, e));
_latch.countDown();
}
public Result<RESP> getResult(final long timeout, final TimeUnit unit) throws InterruptedException, TimeoutException
{
if (!_latch.await(timeout, unit))
{
throw new TimeoutException();
}
return _result.get();
}
You don't need to use another synchronization object (AtomicRefetence) here. The point is that the variable is set before CountDownLatch is invoked in one thread and read after CountDownLatch is invoked in another thread. CountDownLatch already performs thread synchronization and invokes memory barrier so the order of writing before and reading after is guaranteed. Because of this you don't even need to use volatile for that field.
A good starting point is the javadoc (emphasis mine):
Memory consistency effects: Until the count reaches zero, actions in a thread prior to calling countDown() happen-before actions following a successful return from a corresponding await() in another thread.
Now there are two options:
either you never call the onXxx setter methods once the count is 0 (i.e. you only call one of the methods once) and you don't need any extra synchronization
or you may call the setter methods more than once and you do need extra synchronization
If you are in scenario 2, you need to make the variable at least volatile (no need for an AtomicReference in your example).
If you are in scenario 1, you need to decide how defensive you want to be:
to err on the safe side you can still use volatile
if you are happy that the calling code won't mess up with the class, you can use a normal variable but I would at least make it clear in the javadoc of the methods that only the first call to the onXxx methods is guaranteed to be visible
Finally, in scenario 1, you may want to enforce the fact that the setters can only be called once, in which case you would probably use an AtomicReference and its compareAndSet method to make sure that the reference was null beforehand and throw an exception otherwise.
Short answer is you don't need AtomicReference here. You'll need volatile though.
The reason is that you're only writing to and reading from the reference (Result) and not doing any composite operations like compareAndSet().
Reads and writes are atomic for reference variables and for most primitive variables (all types except long and double).
Reference,
Sun Java tutorial
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
Then there is JLS (Java Language Specification)
Writes to and reads of references are always atomic, regardless of whether they are implemented as 32-bit or 64-bit values.
Java 8
http://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.7
Java 7
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7
Java 6
http://docs.oracle.com/javase/specs/jls/se6/html/memory.html#17.7
Source : https://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
Atomic actions cannot be interleaved, so they can be used without fear of thread interference. However, this does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible. Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads. What's more, it also means that when a thread reads a volatile variable, it sees not just the latest change to the volatile, but also the side effects of the code that led up the change.
Since you have only single operation write/read and it's atomic, making the variable volatile will suffice.
Regarding use of CountDownLatch, it's used to wait for n operations in other threads to complete. Since you have only one operation, you can use Condition, instead of CountDownLatch.
If you're interested in usage of AtomicReference, you can check Java Concurrency in Practice (Page 326), find the book below:
https://github.com/HackathonHackers/programming-ebooks/tree/master/Java
Or the same example used by #Binita Bharti in following StackOverflow answer
When to use AtomicReference in Java?
In order for an assignment to be visible across threads some sort of memory barrier must be crossed. This can be accomplished several different ways, depending on what exactly you're trying to do.
You can use a volatile field. Reads and writes to volatile fields are atomic and visible across threads.
You can use an AtomicReference. This is effectively the same as a volatile field, but it's a little more flexible (you can reassign and pass around references to the AtomicReference) and has a few extra operations, like compareAndSet().
You can use a CountDownLatch or similar synchronizer class, but you need to pay close attention to the memory invariants they offer. CountDownLatch, for instance, guarantees that all threads that await() will see everything that occurs in a thread that calls countDown() up to when countDown() is called.
You can use synchronized blocks. These are even more flexible, but require more care - both the write and the read must be synchronized, otherwise the write may not be seen.
You can use a thread-safe collection, such as a ConcurrentHashMap. Overkill if all you need is a cross-thread reference, but useful for storing structured data that multiple threads need to access.
This isn't intended to be a complete list of options, but hopefully you can see there are several ways to ensure a value becomes visible to other threads, and that AtomicReference is simply one of those mechanisms.
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.
Can anyone explain what is unsynchronized & synchronized access in Java Collections Framework?
Synchronized vs unsynchronized access doesn't have to do with the Java Collections Framework per see.
Synchronized access means that you have some sort of locking for accessing the data. This can be introduced by using the synchronized keyword or by using some of the higher level constructs from the java.util.concurrent package.
Unsynchronized access means that you don't have any locking involved when accessing the data.
If you're using a collection in several threads, you better make sure that you're accessing it in a synchronized way, or, that the collection itself is thread safe, i.e., takes care of such locking internally.
To make sure all accesses to some collection coll is accessed in a synchronized way, you can either
...surround accesses with synchronized (coll) { ... }
public void someMethod() {
synchronized (coll) {
// do work...
}
}
...encapsulate it using Collections.synchronizedCollections
coll = Collections.synchronizedCollection(coll);
In the former approach, you need to make sure that every access to the collection is covered by synchronized. In the latter approach, you need to make sure that every reference points at the synchronized version of the collection.
As pointed out by #Fatal however, you should understand that the latter approach only transforms a thread unsafe collection into a thread safe collection. This is most often not sufficient for making sure that the class you are writing is thread safe. For an example, see #Fatals comment.
Synchronized access means it is thread-safe. So different threads can access the collection concurrently without any problems, but it is probably a little bit slower depending on what you are doing.
Unsynchronized is the opposite. Not thread-safe, but a little bit faster.
The synchronized access in Java Collection Framework is normally done by wrapping with Collections.synchronizedCollection(...) etc. and only access through this wrapper.
There are some exceptions already synchronized like Hashtable and Vector.
But keep in mind:
Synchronization is done over the collection instance itself and has a scope for each method call. So subsequent calls maybe interrupted by another thread.
Example:
You first call isEmtpy() method getting result that it is not empty and after that you want to retrieve an element from that collection. But this second method call may fail, because collection may be empty now due to actions by another thread done between your calls.
So even with synchronized collections you've to care about synchronization and it maybe necessary to synchronize yourself outside the collection!
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.