There is a rule to find out, for sure, all objects that could possibly have concurrent access in a Java program? My intention is use such rule, if it exists, to find out which Java classes could possibly have concurrent access and then guarantee that they are thread-safe. This rule could be very useful when inspecting a large Java project. I've thought to look for static methods, but I’m not sure if this is the only way an object can be accessible to multiple threads.
views:
82answers:
6There is a rule to find out which objects could possibly have concurrent access in a Java program?
No, it's not possible to determine this from looking at the method signatures. There is no rule that only static methods can give concurrency problems.
There could also be a problem if two threads share references to the same objects, either directly (by being given a reference to the same object) or indirectly (via static objects, static methods, members of objects used, etc.). It is not always possible to detect these situations using a static analysis of the code.
It seems very, very unlikely that such a thing exists as a single rule. Imagine the following:
public void maybeAccessConcurrently(Program x) {
if(halts(x)) {
accessConcurrentObject();
} else {
// don't.
}
}
I don't know about you, but I can't really contrive a rule that isn't equivalent to deciding the halting problem here, especially not by simple inspection of types or declarations. I think you may find that like other static analysis techniques, there are a set of properties that you can check within reason. The Bandera project appears to be an effort to use various model-checking techniques to verify properties of concurrent Java code. There may be other similar efforts (all of which are most likely to involve model checking, given the presence of concurrency).
I've thought to look for static methods, but I’m not sure if this is the only way an object can be accessible to multiple threads.
No, static methods don't help you at all. You're not even restricted to objects. Even access to primitives may not be thread safe. For example incrementing a long may not be an atomic operation depending on the platform you're running on. Afaik what you're asking is not possible.
I doubt that such a (handy) rule is possible. Consider this:
public MyRunnable implements Runnable {
public run() {
Class.forName("com.example.MainClass").newInstance();
}
}
and later
public class MainClass {
public MainClass() {
startApplication();
}
public static startApplication() {
// A huge application is started
}
}
Now every class that is ever used while executing the "MainClass" application has concurrent access - because you can start the application several times in different threads and you'll never know which class is started (the information is hidden in a String literal) and what other classes may be instantiated.
Yes it is very possible to make such a rule,
public static boolean canBeAccessedConcurrently(Object arg){
return true;
}
Check out static code analyzers FindBugs and PMD. They have a lot of rules that help to find potential concurrency problems. Both can be run from the command line, so you can incorporate them into your build and have the build broken if rules are violated.