Java Exceptions  «Prev  Next»

Lesson 13

Concurrency and Multitasking Conclusion

Many methods in the Java class Thread which represent a thread of control, are declared using the throws keyword. These methods throw exceptions as part of the control flow of working with threads.
The synchronized keyword in Java, particularly in the context of the Java 1.1 event model (and in Java in general), plays a crucial role in thread coordination and synchronization. Here's how it works:
The synchronized Keyword:
  • Purpose: The synchronized keyword is used to prevent thread interference and memory consistency errors by ensuring that a block of code is executed by only one thread at a time.
  • Mechanism: When a thread enters a synchronized block or method, it acquires a lock on the object used for synchronization. Other threads attempting to enter the same synchronized block or method must wait until the lock is released.

Usage in Java 1.1 Event Model:
In the context of Java 1.1's event model, which introduced the AWT (Abstract Window Toolkit) event delegation model, synchronization was crucial for handling events in a thread-safe manner. Here's how synchronized was used:
  1. Event Listeners:Event listeners (like `ActionListener`, `MouseListener`, etc.) were often implemented in a way that required thread safety, especially since events were dispatched in the Event Dispatch Thread (EDT) but could be processed by any thread.
  2. Synchronized Methods/Blocks:- When implementing event listeners, developers would often use synchronized methods or blocks to ensure that shared resources (like UI components or shared data structures) were accessed safely.
    public class MyButtonListener implements ActionListener {
      private JButton button;
    
      public MyButtonListener(JButton button) {
       this.button = button;
      }
    
      public synchronized void actionPerformed(ActionEvent e) {
       // Code to handle the button click
       // This method is synchronized to ensure thread safety
       button.setText("Clicked!");
      }
    }
    


  3. Coordinating Access to Shared Resources: If multiple threads could potentially modify or read shared data (like counters, UI state, etc.), synchronization ensured that these operations were atomic.
    private int clickCount = 0;
    
    public synchronized void incrementClickCount() {
       clickCount++;
    }
    
    public synchronized int getClickCount() {
       return clickCount;
    }
    


Key Points About `synchronized`:
  • Mutual Exclusion: Only one thread can execute a synchronized block or method at a time on the same object.
  • Monitor: The `synchronized` keyword uses the concept of a monitor, which is essentially an object that can be locked. When a thread enters a synchronized block or method, it locks this monitor.
  • Wait and Notify:Often used in conjunction with `synchronized` for more complex thread coordination, allowing threads to wait for conditions to change or notify other threads of changes.
    public synchronized void doSomething() throws InterruptedException {
     while (conditionNotMet) {
        wait(); // Release lock and wait for notification
     }
     // Proceed with the operation
     conditionNotMet = true;
     notifyAll(); // Notify other waiting threads
    }
    
  • Performance:While `synchronized` ensures thread safety, it can introduce performance overhead due to locking and unlocking operations. Java 5 introduced java.util.concurrent package with more efficient synchronization mechanisms like `ReentrantLock`.

Conclusion: In the Java 1.1 event model, and in Java generally, `synchronized` was (and still is) fundamental for ensuring that event handling and access to shared resources are thread-safe. It provides a straightforward way to coordinate between threads, preventing race conditions and ensuring data integrity in multi-threaded environments. However, with the evolution of Java, developers now have more sophisticated tools for concurrency control, though `synchronized` remains a core concept for basic thread synchronization.

Multithreaded versus Multithreading:

  • Multithreaded Java was designed to meet the real-world requirement of creating interactive, networked programs. To accomplish this, Java supports multithreaded programming, which allows you to write programs that do tasks simultaneously. The Java runtime system comes with a sophisticated solution for multiprocess synchronization that enables you to construct smoothly running interactive systems. Java's easy-to-use approach to multithreading allows you to think about the specific behavior of your program, not the multitasking subsystem.
  • Multithreading: Unlike some computer languages, Java provides built-in support for multithreaded programming. A multithreaded program contains two or more parts that can run concurrently. Each part of such a program is called a thread, and each thread denotes a separate path of execution. Hence, multithreading is a specialized form of multitasking. You are almost certainly acquainted with multitasking because it is supported by virtually all modern operating systems. However, there are two distinct types of multitasking:
    1. process-based and
    2. thread-based.
    It is important to understand the difference between the two. For many readers, process-based multitasking is the more familiar form. A process is, in essence, a program that is executing. Thus, process-based multitasking is the feature that allows your computer to run two or more programs concurrently. For example, process-based multitasking enables you to run the Java compiler at the same time that you are using a text editor or visiting a web site. In process-based multitasking, a program is the smallest unit of code that can be dispatched by the scheduler.


SEMrush Software