I am a Java Developer working in Sydney. I am eager to learn new technologies, new frameworks, new languages. Thibault has posted 8 posts at DZone. You can read more from them at their website. View Full User Profile

Java SE 11 : Moving Java Forward – Part 3 : Thread Safe compilation checking

09.13.2012
| 6944 views |
  • submit to reddit

This series of articles presents how, in my opinion, the java language should evolve to remain a top-choice language. It also presents some features, sometimes already existing in other languages, which I love but that cannot (or should never) be part of Java, for reasons that I will explain. I would really love to transform some of those ideas into JSRs one day.

Thread Safe compilation checking: What is it?

Thread Safe Compilation-Checking is the ability to check that your program will not have issues due to multi-threading. As far as I know, no programming language provides this functionality (If you know one, please let me know!).

What is the problem?

Developing a program that runs in several threads is easy, developing something that won't have any weird bugs due to that thread mechanism is far more difficult.

Why is concurrent programming is hard?

Because to make a good multi-thread application, you have to be very careful and know  the Java language and the API perfectly: avoid deadlocks, know when to use the volatile keyword, know what is (or not) thread-safe.

The other difficulty is that testing/debugging a multi-thread application is very hard. You can spend several days wondering why in your huge database you have this row with a weird date value... To finally realize that your co-developer (of course not you, since you are a java guru ;) ) has used a SimpleDateFormat object shared by several threads... (BTW, if you didn't know: yes, SimpleDateFormat is not thread safe.)

What is the solution?

The solution is thread safe compilation checking! It would make the development so much easier if you had a warning telling you "At line 36: Not Thread Safe code. Usage of a non thread safe method SimpleDateFormat.format.”

Why it is impossible

Usage of non-thread-safe APIs

At the moment, the only way to know if the libraries/APIs you are using are thread-safe is to read Javadoc or the source code so the compiler has no way to know if what you call is, or is not, thread-safe. By transitivity, if you are not using any kind of synchronization mechanism,  it has no way to know if your code is thread-safe or not since you are using those libraries.

One solution to this issue could be to create an @ThreadSafe annotation to annotate classes and methods. That way, any element annotated with @ThreadSafe would be considered as thread-safe by the compiler. Of course, all the APIs you use need to be annotated correctly... Apart from the compilation-checking thing, I think that such an annotation would be great to make the APIs clearer.

The Reflection API

The Reflection API is another issue. Since the execution flow is determined during the run-time, the compiler cannot know what methods will be called and so cannot determine if what is going to be executed is thread-safe.

The compiler needs to know the context

The compiler has no way to know if what you are developing is going to be executed in a thread safe environment or not. For example if you are developing a bean that is going to be injected everywhere by your favorite CDI framework, the compiler cannot know it.

In other words, the compiler knows less than you and so cannot determine if what you are programming needs to be thread safe or not. Let's say you are programming a controller for your J2EE application; If you don't annotate your controller with the hypothetical @ThreadSafe annotation, the compiler won't ever complain. The problem is that your controller has to be thread-safe! If you don't annotate correctly with @ThreadSafe what had to be thread safe, you will have issues...

The different locking mechanisms

If the only way to synchronize your threads was the synchronized keyword, it would be easier for the compiler to determine if a piece of code can be run concurrently or not. Unfortunately that isn't the case! You have several ways to ensure that your code will be executed only in the right context (ReentrantLockReadWriteLock, manual locks using a file, a socket, an object, a counter etc...). To me, this is why the "thread-safe compilation checking" is impossible to implement. If the compiler is not able to spot the synchronization mechanism, it can't know anything about thread safety!

Conclusion

Thread-safe compilation checking would definitely be a killer feature. But to me, it is impossible to implement, even partially, and that's probably why I have never seen this feature in any languages.

If you have any ideas of a solution or if you know any language that does it, even partially, let me know!

 

Published at DZone with permission of its author, Thibault Delor.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Sinuhé Pop replied on Fri, 2012/09/14 - 6:16am

I have some similar thoughts:

@ThreadSade is very difficult to implement, requiring a lot of complicated static code analysis. But I think there is a less powerful but easier option I've tried at home with success. Imagine an @Immutable annotation validated at compile-time by an APT. It just has to ensure that all properties of a class (and its superclasses) are final and its type immutable (so, annotated with @Immutable or one of a list of well known immutable objects). Of course, I know that not all thread-safe objects are immutable, but all immutable objects are thread-safe by definition.

It would be great to get methods, properties and constructors of a class at compile-time, as you suggested. There is a couple of options to achieve this: an APT which generates another class with this information or something more complicated that generates some static fields in the same class, like Project Lombok does. 

Anyway, very interesting article. 

Thibault Delor replied on Fri, 2012/09/14 - 6:46am in response to: Sinuhé Pop

Thanks for your comment.

Actually when you say "all immutable objects are thread-safe by definition", I strongly disagree. The definition of an immutable object by definition is an object that has a state that cannot change. Basically it is an object where all fields are final or at least that doesn't have any setters. That has nothing to do with thread safety!

Let say that you have an object that contains only a File object. This File object is final and can be initialized only thanks to the constructor. By definition this  object is immutable. Now let say that you have a method write(String s). If you call in several thread the write method with synchronization mechanism, you will have problems!

So, an immutable makes the concurrency development easier but doesn't guarantee the thread safety at all! 

Sinuhé Pop replied on Fri, 2012/09/14 - 8:06am in response to: Thibault Delor

It's a little tricky matter, but immutable objects are thread-safe (in the link you'll find some good explanations). Your example (java.io.File), well... is THE example :). It's true that it has no mutable fields, but its native functions rely on OS handles that aren't thread-safe. So, probably, File won't be included in the list of well known immutable objects. 

Anyway, what I say are just simplifications. There are other issues that must be thought:

 - Must subclasses of an immutable object be immutable too? I think they must. So, all classes must be validated at compile time (not just the ones annotated) to discover if they inherit from immutable objects (or implement @Immutable annotated interfaces). 

 - And what about collections? Of course only immutable ones will accepted. But APT must validate that they generic types are immutable too. For example, a com.google.common.collect.ImmutableList<java.io.File> won't be accepted.

Well, I think all these can lead to a longer discussion...

Thibault Delor replied on Fri, 2012/09/14 - 10:12pm in response to: Sinuhé Pop

Well, I get your point. I have seen a lot of article about immutability and thread safety and I don't think that in any of this article I have read a definition of immutability that leads to a guarantee of thread safety.

Actually, I think that it is a very interesting subject that needs a complete article ;). I will try to define Immutability and its relation to thread-safety. Stay tuned!

Thanks for your clever comments!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.