The programming language Java supports concurrent programming and all processing is done in threads. In the JVM (Java Virtual Machine) resources can be accessed by any or several of those threads. Each thread can possibly access any object or resource in the program. The programmer in this case must make sure that access to these resources is managed properly. In other words, only one thread can access resources at the time, so all other threads must be prevented from accessing (partially) updated resources. Java as a programming language has some native support for managing access to resources, this is called Java concurrency.
Concurrency is beneficial for several reasons. It can minimize response lag, maximize throughput, simulate autonomous object for modelling and offers exploiting multiprocessors and overlapping I/O for parallelism. Concurrency using Java threads must be protected by locks and such. Implementing concurrency however, results in an increase in complexity and can lead to higher resource usage.
If different threads, either on one core or on multicore, are using a shared resource, a concurrency library is needed. The Java concurrency library provides shared-memory concurrency. Distributed concurrency and message passing require additional frameworks. Because computations in a concurrent system can interact with each other while they are executing, the number of possible execution paths in the system can be extremely large, and the resulting outcome can be Indeterminacy in concurrent computation. Concurrent use of shared resources can be a source of indeterminacy leading to issues such as deadlock, and Resource starvation
Deadlocks can arise when protecting accesses from concurrent threads by locks. This is due to the fact that several threads are trying to access (or even alter) the same memory. With parallel programming these threads can be working at the same time, but with concurrency it can be possible that one thread is paused, and another thread tries to access the same memory. The Java concurrency library provides locks but cannot ensure that deadlocks do not occur. An alternative to using locks is to write code in a message passing style.
Message passing communication makes the concurrent components communicate by exchanging (passing) messages. This message passing can be done by blocking the sender until the message is received or asynchronous. Asynchronous message passing may be reliable or unreliable.
Message passing concurrency tends to be easier to understand than shared memory concurrency because it looks more logical at the first glance. It is considered to be a robust form of concurrent programming. There are various mathematical theories to help understand message passing systems. Examples are the actor model, ambient calculus and Pi-calculus.