Although this applies to any multithreaded environment here I am only asking about Java. And only about pure Java, deadlocks caused by external devices accessed from Java, like database deadlocks, are not the topic of this.
What methodologies and supporting frameworks are there that, when properly used, give a guarantee that your code is deadlock free?
The ones I am aware of are :
No multithreading. Which is the solution used by many GUI frameworks.
Single global lock. Not a good solution since efficiency suffers.
Accessing locks in a fixed order. I know of no framework to support this.
Static analysis is helpful since it can detect many cases of potential deadlocks but gives no guarantees.
Related
As Described here
While locks seem to be the natural remedy to uphold encapsulation with multiple threads, in practice, they are inefficient and easily lead to deadlocks in any application of real-world scale.
My question simply, is akka really a solution for a deadlock.
I know as long as akka actors treat objects as completely decoupled, that code never meets a deadlock scenario. But, in the imperative programming also we can simply decouple them and lock separately without keeping a lock inside another lock, so that won't be a deadlock scenario at all in traditional programming paradigm also. what's the real use case of this statement? Do we find any use case, which can cause deadlock scenario in traditional programming but prevent using akka actor model?
P.S I am very new to akka but, I can understand the call stack, shared memory and threading issues in traditional programming is very costly in the modern computer architecture and akka is a good solution in performance-wise. But curious to know this special statement also.
I consider the Summary of the Discussion in the question thread as the answer.
Basically, Akka doesn't use locks doesn't mean that Akka can prevent deadlocks from real-world deadlock possible scenarios. But, since we think each and every actor as fully decoupled and completely different architecture from multithreaded applications, it performs faster. So,
it's very less probable for a deadlock to happen!
Does anybody know about a tool that allows the explicit switching of threads at certain points in the code?
I am testing Software Transactional Memory for my bachelor thesis and for these tests, I need specific execution orders of threads (e.g. thread 1 reads 2 variables, after that switch to thread 2 and write to a variable, etc.). The problem is, the software library implementing the STM prohibits normal java synchronizaton methods in the code, so I cannot use sychronized blocks, locks or semaphores.
I was hoping someone knows about a tool like Concurrit (https://code.google.com/archive/p/concurrit/), only for Java...
No such tool exists. The only way you could achieve something like this would be to (drastically) modify the JVM itself, replacing the existing thread scheduling mechanisms. That would be an impractically large project ... by itself.
Opinion: the Concurrit DSL is not designed to be a practical programming language, and adding the mechanisms that it provides to a practical programming language most likely would make it it non-performant. Naturally, there is unlikely to be much enthusiasm for implementing such a tool for a performant1 language such as Java.
1 - Relatively speaking.
I was wondering if there is any framework or application(app)/program out there that can analyze the concurrency of any java code?
If the tool knows all the implementations of the jre shipped classes and methods then it comes down to a simple analyzing of synchronized blocks and method and their call hierarchies. From here it can create a petri net and tell you for sure if you could ever experience a deadlock.
Am I missing out on something or is this really so easy? Then there must be some cool tool doing that kind of stuff? Or would such a tool report too many possible deadlocks that are completely save because of some underlying program/business logic? Petri nets should be powerful enough to handle these situations?
This would save so many man hours of searching for bugs that might or might not be related to dead locking issues.
Although (many) concurrency related bugs can be found using static code analysis, it doesn't apply to every type of bug. Some bugs only appear at runtime under certain conditions.
IBM has a tool called ConTest that "schedules the execution of program threads such that program scenarios that are likely to contain race conditions, deadlocks, and other intermittent bugs (collectively called synchronization problems) are forced to appear with high frequency".
This requires running (unit)tests against an instrumented version of your app. More background info in this developerWorks article.
This paper describes a tool that performs static analysis of a library and determines if deadlock is possible.
Some more :
klocwork
CheckThread
I make a tool and provide an API for external world, but I am not sure whether it is thread safe. Because users may want t use it in multiple-thread environment. Is there any way or tool that I can use to verify whether my API is thread safe in Java?
No. There is no such tool. Proving that a complex program is thread safe is very hard.
You have to analyze your program very carefully to ensure that is thread safe. Consider buying "Java concurrency in practice" (very good explanation of concurrency in java).
Stress tests, or static analysis tools like PMD and FindBugs can uncover some concurrency bugs in your code. So these can show if your code is not thread-safe. However they can never prove if it is thread-safe.
The most effective method is a thorough code review by developer(s) experienced in concurrency.
You can always stress-test it with tools like jmeter.
But the main problem with threads is that they're mostly unpredictable, so even with stress-tests etc. you can't be 100% sure that it will be totally thread safe.
Resources :
Wikipedia - Thread-safety
This is a variant (or so called "reduction") of the Halting Problem. Therefore it is provably unsolvable. for all non-trivial cases. (Yes, that's an edit)
That means you can find errors by any usual means (statistics, logic) but you can never completely prove that there are none.
I suppose those people saying proving an arbitrary multithreaded program is thread-safe is impossible are, in a way, correct. An arbitrary multithreaded program, coded without following strict guidelines, simply will have threading bugs, and you can't validly prove something that isn't true.
The trick is not to write an arbitrary program, but one with threading logic simple enough to possibly be correct. This then can be unambiguously validated by a tool.
The best such tool I'm aware of is CheckThread. It works on the basis of either annotations, or xml config files. If you mark a method as '#ThreadSafe' and it isn't, then you get a compile-time error. This is checked by looking at the byte code for thread-unsafe operations, e.g. reads/write sequences on unsynchronised data fields.
It also handles those APIs that require methods to be called on specific threads, e.g. Swing.
It doesn't actually handle deadlocks, but those can be statically eliminated without even requiring annotation, by using a tool such as Jlint. You just need to follow some minimal standards like ensuring locks are acquired according to a DAG, not willy-nilly.
You cannot and never will be able to automatically proof that a program is threadsafe anymore that you can prove that a program is correct (unless you think you solved the halting program, which you didn't).
So, no, you cannot verify that an API is threadsafe.
However in quite some case you can prove that it is broken, which is great!
You may also be interested in automatic deadlock detection, which in quite some case simply "just work". I'm shipping a Java program on hundreds of desktops with such a deadlock detector installed and it is a wonderful tool. For example:
http://www.javaspecialists.eu/archive/Issue130.html
You can also stress test your application in various ways.
Bogus multi-threaded programs tend to not work very well when a high load is present on the system.
Here's a question I asked about how to create easily create a high CPU load on a Un*x system, for example:
Bash: easy way to put a configurable load on a system?
When Java is providing the capabilities for concurrent programming, what are the major advantages in using Clojure (instead of Java)?
Clojure is designed for concurrency.
Clojure provides concurrency primitives at a higher level of abstraction than Java. Some of these are:
A Software Transactional Memory system for dealing with synchronous and coordinated changes to shared references. You can change several references as an atomic operation and you don't have to worry about what the other threads in your program are doing. Within your transaction you will always have a consistent view of the world.
An agent system for asynchronous change. This resembles message passing in Erlang.
Thread local changes to variables. These variables have a root binding which are shared by every thread in your program. However, when you re-bind a variable it will only be visible in that thread.
All these concurrency primitives are built on top of Clojures immutable data structures (i.e., lists, maps, vectors etc.). When you enter the world of mutable Java objects all of the primitives break down and you are back to locks and condition variables (which also can be used in clojure, when necessary).
Without being an expert on Clojure I would say that the main advantage is that Clojure hides a lot of the details of concurrent programming and as we all know the devil is in the details, so I consider that a good thing.
You may want to check this excellent presentation from Rick Hickey (creator of Clojure) on concurrency in Clojure. EDIT: Apparently JAOO has removed the old presentations. I haven't been able to locate a new source for this yet.
Because Clojure is based on the functional-programming paradigm, which is to say that it achieves safety in concurrency by following a few simple rules:
immutable state
functions have no side effects
Programs written thus pretty much have horizontal scalability built-in, whereas a lock-based concurrency mechanism (as with Java) is prone to bugs involving race conditions, deadlocks etc.
Because the world has advanced in the past 10 years and the Java language (!= the JVM) is finding it hard to keep up. More modern languages for the JVM are based on new ideas and improved concepts which makes many tedious tasks much more simple and safe.
One of the cool things about having immutable types is that most of the built-in functions are already multi-threaded. A simple 'reduce' will span multiple cores/processors, without any extra work from you.
So, sure you can be multi-threaded with Java, but it involves locks and whatnot. Clojure is multi-threaded without any extra effort.
Yes, Java provides all necessary capabilities for concurrent programs.
An analogy: C provides all necessary capabilities for memory-safe programs, even with lots of string handling. But in C memory safety is the programmer's problem.
As it happens, analyzing concurrency is quite hard. It's better to use inherently safe mechanisms rather than trying to anticipate all possible concurrency hazards.
If you attempt to make a shared-memory mutable-data-structure concurrent program safe by adding interlocks you are walking on a tightrope. Plus, it's largely untestable.
One good compromise might be to write concurrent Java code using Clojure's functional style.
In addition to Clojure's approach to concurrency via immutable data, vars, refs (and software transactional memory), atoms and agents... it's a Lisp, which is worth learning. You get Lisp macros, destructuring, first class functions and closures, the REPL, and dynamic typing - plus literals for lists, vectors, maps, and sets - all on top of interoperability with Java libraries (and there's a CLR version being developed too.)
It's not exactly the same as Scheme or Common Lisp, but learning it will help you if you ever want to work through the Structure and Interpretation of Computer Programs or grok what Paul Graham's talking about in his essays, and you can relate to this comic from XKCD. ;-)
This video presentation makes a very strong case, centred around efficient persistent data structures implemented as tries.
Java programming language evolution is quite slow mainly because of Sun's concern about backward compatibility.
Why don't you want just directly use JVM languages like Clojure and Scala?