Java has come a long way. A very long way. And it carries with it all the “junk” from early day design decisions.
One thing that has been regretted time and again is the fact that
every object (potentially) contains a monitor. This is hardly ever necessary and this flaw was corrected, finally, in Java 5, when new concurrency APIs were introduced, such as the
java.util.concurrent.locks.Lock
and its subtypes. Since then, writing synchronized, concurrent code has become a lot easier than before when we only had the
synchronized
keyword and the hard-to-understand
wait()
and
notify()
mechanism:
The synchronized modifier is hardly used anymore
The original language design specified for these “convenience” modifiers on methods:
// These are the same, semantically:
public synchronized void method() {
...
}
public void method() {
synchronized (this) {
...
}
}
// So are these:
public static synchronized void method() {
...
}
public static void method() {
synchronized (ClassOfMethod.class) {
...
}
}
(note, while the byte code produced above is not the same, the high level semantics certainly is)
You hardly want to synchronize on the complete method scope, in order to keep synchronization time at a minimum, and factoring out a method every time you need synchronization is tedious.
Furthermore, the monitor breaks encapsulation. Everyone can synchronize on your monitor if you synchronize on
this
or on the entire
class
. You probably don’t want that, which is why most people who still do work with the
synchronized
keyword will simply create an explicit, private lock object, such as:
class SomeClass {
private Object LOCK = new Object();
public void method() {
...
synchronized (LOCK) {
...
}
...
}
}
If that’s the standard use-case for classic
synchronized
blocks, do we then still need a monitor on every object?
Synchronized in a more modern Java version
If Java were designed with today’s knowledge about the Java language, we wouldn’t allow for using
synchronized
on any random object (including strings or arrays):
// Wouldn't work
synchronized ("abc") {
...
}
We would introduce a special
Synchronizable
marker interface, which guarantees that implementors will have a monitor. And the
synchronized
block would only accept
Synchronizable
arguments:
Synchronizable lock = ...
synchronized (lock) {
...
}
This would work exactly the same way as foreach or try-with-resources:
Iterable<Object> iterable = ...
// The type to the right of ":" must be Iterable
for (Object o : iterable) {
...
}
// The assignment type must be AutoCloseable
try (AutoCloseable closeable = ...) {
...
}
// The assignment type must be a functional interface
Runnable runnable = () -> {};
So, in order for a given language feature to work, the Java language imposes constraints on the types that are used in that context. In the case of foreach or try-with-resources, a concrete JDK type is required. In the case of lambda expressions, a matching structural type is required (which is rather esoteric but clever, for Java).
Unfortunately, for backwards-compatibility reasons, there will not be any new restriction added for
synchronized
blocks. Or will there? It would be great, and an optional warning could be issued if the type is not
Synchronizable
. This might allow, in the course of a couple of future major releases, to remove monitors from objects that are not really required to be synchronizable.
Which is essentially what the C language has been doing with mutexes all along. They’re a special thing. Not the common thing.
Like this:
Like Loading...
Is there a way to make JOOQ work in Netbeans . Perhaps there is somewhere an “ho to” but I cannot find out how it should work . I’m new to JOOQ and considering to use it for a new project.
The best place to start is probably the tutorial, which uses Maven and which is independent of your IDE:
https://www.jooq.org/doc/latest/manual/getting-started/tutorials/jooq-in-7-steps
What issues are you running into?
The two synchronized methods you give are very different at the byte code level, they are not the same thing.
http://www.artima.com/insidejvm/ed2/threadsynchP.html
You’re right, they are not the exact same thing, technically, although semantically (on a higher level), they are.
Seems you read the same posts as I do, learn Swift in sync. Funny. I just wanted to write an article about that, draft is in my wordpress editor, now obsolete.
I guesst the idea of this article was triggered from reading the Value Type article http://cr.openjdk.java.net/~jrose/values/values-0.html
Hmm, no, I hadn’t read that post – seems like an interesting coincidence, then. Indeed, I’m aware of the value type proposal for JDK 10, and it will make these thoughts obsolete, hopefully
“We would introduce a special Synchronizable marker interface”
Why would it be a marker interface? It should be a final class. What else could you use a lock in addition to lock on it without breaking the single responsibility principle?
Perhaps. OTOH, there are some interesting thoughts in this discussion:
https://www.reddit.com/r/programming/comments/40mijj/if_java_were_designed_today_the_synchronizable/cywg6l5
Based on our experience with Plumbr lock contention monitoring, indeed, the design of the original synchronization via monitors carries a heavy cost. In almost half of the applications we end up monitoring, the engineering is surprised to see how badly the synchronized code performs due to the way the concurrent aspects were designed in the application.
It is just so easy to misuse the “synchronized” concept, it is no wonder it happens. Based on the experience we ended up outlining the most common “antipatterns” in https://plumbr.eu/blog/locked-threads/improving-lock-performance-in-java.
Full disclosure: I am affiliated with Plumbr
Very interesting, thanks for sharing!