📜  Java并发中Lock和Monitor的区别

📅  最后修改于: 2022-05-13 01:54:31.907000             🧑  作者: Mango

Java并发中Lock和Monitor的区别

Java并发基本上处理多线程和其他并发操作等概念。这样做是为了确保最大限度和有效地利用 CPU 性能,从而减少一般的空闲时间。在监视器开始使用之前,锁已经存在以实现多线程。那时,锁(或互斥量)是程序内部线程的一部分,用于与其他线程同步的标志机制。它们一直作为一种工具来提供对资源和共享对象的同步访问控制。随着进一步的进步,监视器的使用开始作为一种处理访问和协调线程的机制,这被证明在面向对象的程序中更有效、无错误和兼容。在我们继续寻找两者之间的差异之前,让我们仔细研究一下它们中的每一个。

锁(或互斥)概述

锁最初用于线程的逻辑部分,用于提供线程之间的同步访问控制。线程通过附加到对象的标志来检查对共享对象的访问控制的可用性,这些标志指示共享资源是空闲(解锁)还是忙碌(锁定)。现在,并发 API 提供了在Java使用锁接口显式使用锁的支持。与使用监视器的锁的隐式实现相比,显式方法具有更精细的控制机制。在我们继续讨论监视器之前,让我们看一个演示基本锁功能的插图。

监视器 – 概述



Java Concurrency 中的监视器是一种同步机制,它提供了多线程的基本要求,即各种线程之间的互斥以及执行常见任务的线程之间的协作。监视器基本上“监视”线程间共享资源和对象的访问控制。使用这种构造,一次只有一个线程获得对资源临界区的访问控制,而其他线程则被阻塞并等待特定条件。在Java,监视器是使用 synchronized 关键字(同步块、同步方法或类)实现的。例如,让我们看看两个线程 t1 和 t2 如何同步以使用共享数据打印机对象。

Java
// Java Program to Illustrate Monitoe in Java Concurrency
 
// Importing input output classes
import java.io.*;
 
// Class 1
// Helepr class
class SharedDataPrinter {
 
    // Monitor implementation is caried on by
    // Using synchronous method
 
    // Method (synchronised)
    synchronized public void display(String str)
    {
 
        for (int i = 0; i < str.length(); i++) {
            System.out.print(str.charAt(i));
 
            // Try-catch bloc kfor exceptions as we are
            // using sleep() method
            try {
 
                // Making thread to sleep for very
                // nanoseconds as passed in the arguments
                Thread.sleep(100);
            }
            catch (Exception e) {
            }
        }
    }
}
 
// Class 2
// Helper class extending the Thread class
class Thread1 extends Thread {
 
    SharedDataPrinter p;
 
    // Thread
    public Thread1(SharedDataPrinter p)
    {
 
        // This keyword refers to current instance itself
        this.p = p;
    }
 
    // run() method for this thread invoked as
    // start() method is called in the main() method
    public void run()
    {
 
        // Print statement
        p.display("Geeks");
    }
}
 
// Class 2 (similar to class 1)
// Helper class extending the Thread class
class Thread2 extends Thread {
 
    SharedDataPrinter p;
 
    public Thread2(SharedDataPrinter p) { this.p = p; }
 
    public void run()
    {
 
        // Print statement
        p.display(" for Geeks");
    }
}
 
// Class 3
// Main class
class GFG {
 
    // Main driver method
    public static void main(String[] args)
    {
 
        // Instance of a shared resource used to print
        // strings (single character at a time)
        SharedDataPrinter printer = new SharedDataPrinter();
 
        // Thread objects sharing data printer
        Thread1 t1 = new Thread1(printer);
        Thread2 t2 = new Thread2(printer);
 
        // Calling start methods for both threads
        // using the start() method
        t1.start();
        t2.start();
    }
}



输出:

最后,让我们讨论一下Java并发中 Lock 和 Monitor 之间的主要区别,如下图所示:



Lock (Mutex)

Monitor

Have been used since the coining of Multithreading concepts.Came into existence with later developments in the field.
Usually in the form of a data field or flag that helps implement coordination. Synchronicity is implemented via a construct mechanism.A similar
Critical Section (the lock/unlock functions and other operations on the shared object) is a part of the thread itself. Similar mechanism of lock/unlock for synchronization along with operational functions (such as read/write) is present with the shared object only.
Implementation of mutual exclusion (execution of one thread preventing others’ execution) and cooperation (threads working on a common task) is the responsibility of the threads. Mutual Exclusion between different set of threads and cooperation (if needed) is all handled by the shared resource itself.
Loosely linked mechanism as all the threads are independent and handle their synchronization in access control themselves.The mechanism is quite robust and reliable as everything is managed at the resource side only.
This method is highly prone to errors when locking time and the constructed mechanism use thread synchronization operation time slice are comparable. There is a good chance that while a thread puts a lock its time slice gets over and the other thread starts working on the resource.The monitors are well designed to work with small thread pools and perform very efficiently unless inter thread communication becomes a necessity.
Ready queue or thread pools are either not present or else handled by the operating system.Threads wait in queues managed by the shared object they all are trying to access control over.
Locks independently are not much in use and are implemented much less widely. Monitors intrinsically use inter-thread locks only and are much more in usage.