Java Concurrency
Santosh Jadhavar
Java Developer | J2EE Specialist | TDD | Oracle Certified Java Associate | Agile Methodologies |Learning Generative AI
1.What is Concurrency?
Concurrency is the concept of executing two or more tasks at the same time (in parallel). Tasks may include methods (functions), parts of a program, or even other programs.
2.Concurrency in Java: -
The Java Platform has always offered support for concurrent programming, which was the basis for implementing many of the services offered by Java EE containers. At Java SE 5, additional high-level API support for concurrency was provided by the java.util.concurrent package.
3.Threads vs Processes:-
Processes-
In the simplest terms, a process is a program in execution. Each process has its own memory space, including the heap and stack memory. Consider it as a separate entity entirely. The Operating System manages these processes, deciding when they run and managing their resources. Here's an example of starting a new process in Java:
Process process = Runtime.getRuntime().exec("notepad.exe");
The above code starts a new process that opens Notepad.
?
Thread-
A thread, on the other hand, is the smallest unit of execution within a process. If a process is a program in action, a thread is a pathway through which the program runs. A single process can have multiple threads, all sharing the same memory space. This shared memory model enables threads to communicate with each other more easily compared to processes.
?A] Creating Threads in Java
?? Java offers two primary ways to create a thread:
?1] Extending the Thread Class:
?2] Implementing the Runnable Interface
?
B] Thread Lifecycle in Java
Understanding the lifecycle of a thread is crucial in concurrency. A thread in Java can be in one of the following states:
?
1.????? New: When a thread is created, it’s in the new state and not yet started.
2.????? Runnable: Once start() is invoked, the thread is in the runnable state, where it's executing or ready to execute.
3.????? Blocked/Waiting: A thread can enter this state when it’s waiting for a resource or another thread.
4.????? Timed Waiting: When a thread is sleeping or waiting for a certain period.
5.????? Terminated: Once the run() method exits, the thread is terminated.
?
4.Pros of Concurrency
Here are the key benefits of concurrency:
1.????? Enhanced Efficiency: Concurrency enables the simultaneous execution of multiple applications, leading to increased efficiency and overall productivity of workstations.
2.????? Optimized Resource Usage: It facilitates better utilization of resources by allowing unused assets or data to be accessed by other applications in an organized manner.
3.????? Improved System Performance: This is achieved by enabling various hardware resources to be accessed concurrently by different applications or threads.
5.Cons of Concurrency
Here are some challenges of concurrency:
1.????? Minimizing Interference: When multiple applications run concurrently, it’s crucial to safeguard them from causing disruptions to each other’s operations.
2.????? Coordinated Execution: Applications running in parallel need careful coordination, synchronization, and well-organized scheduling.
3.????? Coordinating Systems: Designing additional systems becomes necessary to manage the coordination among concurrent applications effectively.
4.????? Increased Complexity: Operating systems encounter greater complexity and performance overheads when switching between various applications running in parallel.
5.????? Performance Impact: Too many simultaneous processes can lead to decreased or degraded overall system performance.
Considering these considerations helps us understand the complexities and challenges concurrency can bring during process planning.
6.Issues of Concurrency
Understanding Concurrency Challenges:
1.????? Non-Atomic Operations: When operations aren’t atomic, other processes can interrupt them, causing issues. An atomic operation happens independently of other processes or threads. Any operation that relies on another process is non-atomic, which can lead to problems.
2.????? Race Conditions: It’s when the output of a program depends on the unpredictable timing or sequence of events. This often happens in software that handles multiple tasks simultaneously, threads that cooperate, or when sharing resources. It’s like trying to cross a busy intersection without traffic lights!
领英推荐
3.????? Blocking: Imagine a process putting its work on hold while it waits for something else to happen, like a resource becoming available or an input operation finishing. It’s like waiting for a green light to move forward. But if a process gets stuck waiting a long time, it’s not pleasant, especially when regular updates are needed.
4.????? Starvation: In concurrent computing, starvation occurs when a process is continuously denied the resources it needs to do its job. It can be caused by errors in how resources are allocated or managed.
5.????? Deadlock: That’s a deadlock. In the computing world, it’s when processes or threads are stuck waiting for each other to release a lock or send a message. Deadlocks can occur in systems where processes share resources, like in parallel computing or distributed systems.
7. Thread Safety
1]Atomic classes and variable
- Java Atomic Classes are a set of classes provided by the java.util.concurrent.atomic package that encapsulate primitive data types and provide atomic operations for concurrent programming. These classes ensure thread safety without the need for explicit synchronization mechanisms such as locks or synchronized blocks.
- Atomic variable: AtomicInteger, AtomicLong, AtomicBoolean, etc.: Java provides atomic classes for various primitive data types, including integers, longs, booleans, and references. These classes encapsulate their respective data types and provide atomic operations for reading, writing, and updating their values.
Atomic Operations: These operations are guaranteed to be performed atomically, without interference from other threads
Popular atomic methods
1.????? set(int value): Sets to the given value
2.????? get(): Gets the current value
3.????? lazySet(int value): Eventually sets to the given value
4.????? compareAndSet(int expect, int update): Atomically sets the value to the given updated value if the current value == the expected value
5.????? addAndGet(int delta): Atomically adds the given value to the current value
6.????? decrementAndGet(): Atomically decrements by one the current value
2] Synchronization in Java
A mechanism that controls how multiple threads access shared resources
2.1] Synchronized Methods:
-? You can define an entire method as synchronized. This means that the method can be accessed by only one thread at a time per instance of the class.
-? It’s a simple way to achieve synchronization but can lead to reduced performance if the method contains time-consuming operations that don’t need synchronization.?
2.2] Synchronized Blocks:
-? Synchronized blocks allow you to synchronize a specific part of a method or a specific object.
-? This approach is more flexible and often leads to better performance, as it reduces the time that a lock is held.
3] Lock Objects:
The java.util.concurrent.locks package provides a framework for locking and waiting for conditions that's more flexible than synchronized methods and blocks.
Locks allow more granular control over the lock acquisition and release.
?4] Volatile Keyword
In addition to synchronized methods and blocks, Java provides the volatile keyword. When a field is declared as volatile, it ensures that updates to that field are immediately visible to other threads.
?
5] Concurrent Collections
Java provides thread-safe variants of standard collections, such as ConcurrentHashMap, CopyOnWriteArrayList, and BlockingQueue. These collections help in managing data in a multi-threaded environment.
1.????? ConcurrentHashMap: A thread-safe variant of HashMap.
2.????? CopyOnWriteArrayList: A variant of List where all mutative operations (add, set, and so on) are implemented by making a fresh copy.
3.????? BlockingQueue: A Queue that additionally supports operations that wait for the queue to become non-empty when retrieving an element, and wait for space to become available in the queue when storing an element.
?
6] Executors and Executor Services
The Java ExecutorService is the interface which allows us to execute tasks on threads asynchronously. The Java ExecutorService interface is present in the java.util.concurrent package. The ExecutorService helps in maintaining a pool of threads and assigns them tasks. It also provides the facility to queue up tasks until there is a free thread available if the number of tasks is more than the threads available.
Code Example: Using ExecutorService
?Conclusion:
Multithreading in Java is a powerful tool for achieving concurrent execution. By using various concepts such as creating and starting threads, thread synchronization, managing deadlocks, thread coordination, and ensuring thread safety, will developing efficient and responsive applications. These mechanisms allow for parallel task execution, resource management, and safe data access, making your programs more robust and scalable.