Ive seen object monitors used in java several times, but it seems to me that any object monitor logic can easily be replaced by use of synchronized code blocks and/or methods.
What is the purpose for using an explicit object monitor rather than just carefully coordinating synchronized code blocks along with Atomic primitives ?
There is always a monitor object. When you have synchronized block, your class instance is the monitor object.
So reasons to use explicit objects:
1) you can share them between class instances to synch access to a shared resource
2) more explicit
3) you can give your monitor object a helpful name
4) more flexible
You're making a distinction where none exists (or are using uncommon terminology). In Java terms, a monitor is the object used as parameter to a synchronized block (or, in the case of synchronized instance methods, implicitly the this instance, and with synchronized static method the class instance).
The main thing is that a normal synchronized block uses the enclosing object as its monitor, in other words, it's equivalent to using synchronized(this) { }. The problem is one of scoping/visibility: any class external to your class can choose to synchronize on the same instance and interfere with your synchronization logic. By using a private final reference as the monitor, this is no longer possible (assuming no reflection shenanigans).
This is formulated in Java Concurrency In Practice as follows (p61, section 4.2.1):
There are advantages to using a private lock object instead of an object's intrinsic lock (or any other publicly accessible lock). Making the lock object private encapsulates the lock so that client code cannot acquire it, whereas a publicly accessible lock allows client code to participate in its synchronization policy -- correctly or incorrectly. Clients that improperly acquire another object's lock could cause liveness problems, and verifying that a publicly accessible lock is properly used requires examining the entire program rather than a single class.
but it seems to me that any object monitor logic can easily be replaced by use of synchronized code blocks and/or methods.
Yes, this is true for the same reason that a glass of water can easily be replaced by a glass of water - they're the same thing. Java's synchronized code blocks and methods expose the monitor pattern at the language level.
Related
Let non-threadsafe, mutable object X be constructed in thread A. A passes X, post construction, to thread B. B mutates X and A never accesses X again.
Will the state of X always be properly visible to B?
Is X effectively thread confined?
My reading of Java Concurrency in Practice seems to indicate that X is not properly published but I cannot cause any problems for thread B in test rigs that run millions of replications. I suspect this is just dumb luck.
For background, X represents a multitude of complex classes over which I have no control that are authored by modelers who have only a basic knowledge of Java. It is strongly preferred that X has no synchronized blocks or other concurrency mechanisms or requirements.
I am currently solving this problem by having thread A pass a thread-safe factory for X that B invokes, thus making X thread confined.
Publication only safe for final fields
The Java Memory Model doesn't guarantee that the object X will be completely published (fully constructed) to thread A.
To ensure that, you would need to make it immutable (all member fields final) or synchronize.
Quoting JSR-133:
The semantics of final fields have been strengthened to allow for thread-safe immutatability
without explicit synchronization. This may require steps such as store-store barriers at the
end of constructors in which final fields are set.
Only thing you need to avoid is leaking fields out of the class before the constructor finishes.
Testing
jcstress has in fact a sample project to demonstrate consequences of racing during publication: JMMSample_06_Finals.java
Note that some efforts had to be done to replicate the problem, like using many fields.
The implementation of the JMM depends naturally on the particular JRE that you are using and also the effects of memory barriers being used depend on the hardware being used.
On my hardware using Oracle JDK 8 I'm not able to reproduce unsafe publication using the sample with jcstress.
Synchronizing
There is a "happens-before" relationship between all synchronization actions. This is known as the synchronization order. Basically when you use any synchronization mechanism, you have the guarantee that actions before it will be visible after it.
As concluded in the Java Language Specification:
If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent
In practice
In practice it's very hard to run into problems due to actions taken in a constructor not being visible by threads using the object.
A primary reason is the usage of synchronization mechanisms. You can check some of the actions that will ensure the happens-before relationship in the javadoc: Memory Visibility
Also as I mentioned with the jcstress sample, JRE nowadays seems to be very good in ensuring consistent results even when it doesn't need to according to the language specification.
I am using spring jdbctemplate in my application and in my query I am using row mapped as new BeanPropertyRowMapper(dto.class)
But I am getting comment from my client to make row mapped thread safe. How it can be done?
The query method looks like:
jdbcTemplate.query(qry, new Object[]("abc"),
new BeanPropertyRowMapper<dto>(dto.class))
Your code is already thread-safe. But you can improve its performance by creating a constant.
The BeanPropertyRowMapper class has mutable data. But once initialized, those data don't change so the class is thread-safe.
Exemple:
private static final BeanPropertyRowMapper<dto> DTO_ROW_MAPPER = new dto<dto>(DtoDetailEvenement.class);
...
jdbcTemplate.query(qry, new Object[]("abc"), DTO_ROW_MAPPER)
Given this code called from a DAO instance method:
jdbcTemplate.query(qry, new Object[]("abc"), new BeanPropertyRowMapper<dto>(dto.class))
(where jdbcTemplate is an instance member of the DAO injected by Spring, and the DAO is a Spring-managed bean with singleton scope) then this seems ok. BeanPropertyRowMapper is stateful and would not be threadsafe if used concurrently by multiple threads, but you're not exposing it to multiple threads, you're using it in a thread-confined manner which is safe.
Java Concurrency in Practice, section 3.3, discusses thread-confinement in general:
Accessing shared, mutable data requires using synchronization; one way to avoid this requirement is to not share. If data is only accessed from a single thread, no synchronization is needed. This technique, thread confinement, is one of the simplest ways to achieve thread safety. When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not [CPJ 2.3.2].
It also discusses (in 3.3.2) the particular kind of thread-confinement that you're doing:
Stack confinement is a special case of thread confinement in which an object can only be reached through local variables. Just as encapsulation can make it easier to preserve invariants, local variables can make it easier to confine objects to a thread. Local variables are intrinsically confined to the executing thread; they exist on the executing thread's stack, which is not accessible to other threads. Stack confinement (also called within-thread or thread-local usage, but not to be confused with the ThreadLocal library class) is simpler to maintain and less fragile than ad-hoc thread confinement.
The only reference to the RowMapper is on the stackframe created for that method call. No other thread (including threads calling the same method on the same DAO) can access it. Tell your client this object is already safe due to being reachable only by local variables, and refer him to the quoted passage from the JCIP book, which is an authoritative reference.
Making every object lockable looks like a design mistake:
You add extra cost for every object created, even though you'll actually use it only in a tiny fraction of the objects.
Lock usage become implicit, having lockMap.get(key).lock() is more readable than synchronization on arbitrary objects, eg, synchronize (key) {...}.
Synchronized methods can cause subtle error of users locking the object with the synchronized methods
You can be sure that when passing an object to a 3rd parting API, it's lock is not being used.
eg
class Syncer {
synchronized void foo(){}
}
...
Syncer s = new Syncer();
synchronize(s) {
...
}
// in another thread
s.foo() // oops, waiting for previous section, deadlocks potential
Not to mention the namespace polution for each and every object (in C# at least the methods are static, in Java synchronization primitives have to use await, not to overload wait in Object...)
However I'm sure there is some reason for this design. What is the great benefit of intrinsic locks?
You add extra cost for every object created, even though you'll
actually use it only in a tiny fraction of the objects.
That's determined by the JVM implementation. The JVM specification says, "The association of a monitor with an object may be managed in various ways that are beyond the scope of this specification. For instance, the monitor may be allocated and deallocated at the same time as the object. Alternatively, it may be dynamically allocated at the time when a thread attempts to gain exclusive access to the object and freed at some later time when no thread remains in the monitor for the object."
I haven't looked at much JVM source code yet, but I'd be really surprised if any of the common JVMs handled this inefficiently.
Lock usage become implicit, having lockMap.get(key).lock() is more
readable than synchronization on arbitrary objects, eg, synchronize
(key) {...}.
I completely disagree. Once you know the meaning of synchronize, it's much more readable than a chain of method calls.
Synchronized methods can cause subtle error of users locking the
object with the synchronized methods
That's why you need to know the meaning of synchronize. If you read about what it does, then avoiding these errors becomes fairly trivial. Rule of thumb: Don't use the same lock in multiple places unless those places need to share the same lock. The same thing could be said of any language's lock/mutex strategy.
You can be sure that when passing an object to a 3rd parting API, it's
lock is not being used.
Right. That's usually a good thing. If it's locked, there should be a good reason why it's locked. Other threads (third party or not) need to wait their turns.
If you synchronize on myObject with the intent of allowing other threads to use myObject at the same time, you're doing it wrong. You could just as easily synchronize the same code block using myOtherObject if that would help.
Not to mention the namespace polution for each and every object (in C#
at least the methods are static, in Java synchronization primitives
have to use await, not to overload wait in Object...)
The Object class does include some convenience methods related to synchronization, namely notify(), notifyAll(), and wait(). The fact that you haven't needed to use them doesn't mean they aren't useful. You could just as easily complain about clone(), equals(), toString(), etc.
Actually you only have reference to that monitor in each object; the real monitor object is created only when you use synchronization => not so much memory is lost.
The alternative would be to add manually monitor to those classes that you need; this would complicate the code very much and would be more error-prone. Java has traded performance for productivity.
One benefit is automatic unlock on exit from synchronized block, even by exception.
I assume that like toString(), the designers thought that the benifits outweighed the costs.
Lots of decisions had to be made and a lot of the concepts were untested (Checked exceptions-ack!) but overall I'm sure it's pretty much free and more useful than an explicit "Lock" object.
Also do you add a "Lock" object to the language or the library? Seems like a language construct, but objects in the library very rarely (if ever?) have special treatment, but treating threading more as a library construct might have slowed things down..
I know using volatile keyword in Java we get some kind of weak synchronization (It allows visibility updates but do not provide actual locking). Is there any situation where volatile should be given preference over actual locking in implementing concurrent programs. A somewhat similar question is there on SO which says volatile as a synchronization mechanism but that was tagged to C#.
If the shared state consists in a single field, and you don't use any get-and-set construct (like i++ for example) to assign it, then volatile is good enough. Most of the volatile usages can be replaced by the use of AtomicXxx types, though (which provide atomic get-and-set operations).
In short, you should prefer to avoid locks wherever they are not necessary since locks expose your program to deadlocks and deter performance by excluding concurrency from critical parts of code. So, whenever the situation permits, by all means rely on volatile; if all you additionally need is atomic two-step operations like compare-and-swap, use AtomicReference. Fall back to synchronized only for the scenarios where this is the only option. For example, if you need to lazily initialize a heavy object, you'll need locks to prevent double initialization—but again, not to fetch the already initialized instance (double-check idiom).
Volatile guarantees that all threads will see the last write of a variable by any other thread, that's it. There's no synchronization involved. If you synchronize both read and write method of an instance variable, then you don't have to make that variable volatile (all threads will see the most recent write).
I am writing a class of which will be created quite a few instances. Multiple threads will be using these instances, so the getters and setters of the fields of the class have to be concurrent. The fields are mainly floats. Thing is, I don't know what is more resource-hungry; using a synchronized section, or make the variable something like an AtomicInteger?
You should favor atomic primitives when it is possible to do so. On many architectures, atomic primitives can perform a bit better because the instructions to update them can be executed entirely in user space; I think that synchronized blocks and Locks generally need some support from the operating system kernel to work.
Note my caveat: "when it is possible to do so". You can't use atomic primitives if your classes have operations that need to atomically update more than one field at a time. For example, if a class has to modify a collection and update a counter (for example), that can't be accomplished using atomic primitives alone, so you'd have to use synchronized or some Lock.
The question already has an accepted answer, but as I'm not allowed to write comments yet here we go. My answer is that it depends. If this is critical, measure. The JVM is quite good at optimizing synchronized accesses when there is no (or little) contention, making it much cheaper than if a real kernel mutex had to be used every time. Atomics basically use spin-locks, meaning that they will try to make an atomic change and if they fail they will try again and again until they succeed. This can eat quite a bit of CPU is the resource is heavily contended from many threads.
With low contention atomics may well be the way to go, but in order to be sure try both and measure for your intended application.
I would probably start out with synchronized methods in order to keep the code simple; then measure and make the change to atomics if it makes a difference.
It is very important to construct the instances properly before they have been used by multiple threads. Otherwise those threads will get incomplete or wrong data from those partially constructed instances. My personal preference would be to use synchronized block.
Or you can also follow the "Lazy initialization holder class idiom" outlined by Brain Goetz in his book "Java concurrency in Practice":
#ThreadSafe
public class ResourceFactory {
private static class ResourceHolder {
public static Resource resource = new Resource();
}
public static Resource getResource() {
return ResourceHolder.resource;
}
}
Here the JVM defers initializing the ResourceHolder class until it is actually used. Moreover Resource is initialized with a static initializer, no additional synchronization is needed.
Note: Statically initialized objects require no explicit synchronization either during construction or when being referenced. But if the object is mutable, synchronization is still required by both readers and writers to make subsequent modifications visible and also to avoid data corruption.