In Java, what is the difference between a monitor and a lock
Asked Answered
P

6

17

Using the synchronized keyword method, using the javap command to view the bytecode, it is found that monitor is used, and if it is possible to call the monitor when the synchronized is implemented, is that my understanding, right? Please correct it if you do not. What is the relationship between them? What is the relationship between the lock and the monitor?

Pontifical answered 2/4, 2018 at 11:43 Comment(0)
C
11

From the official documentation of Locks and Synchronization:

  • Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.")
  • Every object has an intrinsic lock associated with it. By convention, a thread has to acquire the object's monitor lock before accessing them, and then release the monitor lock when it's done with them. A thread is said to own the lock between the time it has acquired the lock and released the lock. As long as a thread owns a monitor lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.
  • When a thread releases the lock, a happens-before relationship is established between that action and any subsequent acquisition of the same lock.

So a monitor and a lock can not be compared for differences, rather they are complementary to each other. Every object in Java is associated with a monitor which a thread can lock or unlock.

Culet answered 2/4, 2018 at 12:13 Comment(2)
@Harash can you describe the relationship between these two notions? What is the exact relation between a monitor and a lock? Are locks the subset of monitors, or vice versa? Are locks just an implementation of monitors (while monitors are an abstract concept)? So far I was unable to find any concrete answer to this question.Philemol
"So a monitor and a lock can not be compared for differences, rather they are complementary to each other." How does that follow from the source you quoted? It seems that the terms "lock" and "monitor" are synonyms in this context.Julienne
S
6

Locks

A lock is kind of data which is logically part of an object’s header on the heap memory. Each object in a JVM has this lock (or mutex) that any program can use to coordinate multi-threaded access to the object. If any thread want to access instance variables of that object; then thread must “own” the object’s lock (set some flag in lock memory area). All other threads that attempt to access the object’s variables have to wait until the owning thread releases the object’s lock (unset the flag).

Once a thread owns a lock, it can request the same lock again multiple times, but then has to release the lock the same number of times before it is made available to other threads. If a thread requests a lock three times, for example, that thread will continue to own the lock until it has “released” it three times.

Please note that lock is acquired by a thread, when it explicitly ask for it. In Java, this is done with the synchronized keyword, or with wait and notify.

Monitors

Monitor is a synchronization construct that allows threads to have both mutual exclusion (using locks) and cooperation i.e. the ability to make threads wait for certain condition to be true (using wait-set).

In other words, along with data that implements a lock, every Java object is logically associated with data that implements a wait-set. Whereas locks help threads to work independently on shared data without interfering with one another, wait-sets help threads to cooperate with one another to work together towards a common goal e.g. all waiting threads will be moved to this wait-set and all will be notified once lock is released. This wait-set helps in building monitors with additional help of lock (mutex).

For more clarification refer -

UNDERSTANDING THREADS, MONITORS AND LOCKS

Difference between lock and monitor – Java Concurrency

Smear answered 2/4, 2018 at 12:21 Comment(1)
Nice answer. Your first link has expired ,fyi.Lethargic
H
5

The doc https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html might not be a very good place to figure out the difference between Lock and Monitor, especially the terms it mentioned: intrinsic lock, monitor lock and simply monitor, which seems suggest that monitor and lock are interchangeable.

This is not true.

Monitor is a structure used for multi-thread synchronization. It consists of a lock and several condition variables. A condition variable is a queue that threads can put them on when a given condition is not as desired. Some other thread can wake these threads up when it makes the condition true. Condition Variable is a way helps threads cooperating with each other.

In simple synchronization cases, we only make use of the lock the monitor provided, like this example:

class SimpleCase {
  int counter;

  synchronized inc() int {
    return counter++;
  }
} 

Threads doing inc() needs no cooperation, only lock is needed to make the threads mutually exclusive, thus makes the counter thread safe.

While in more complicated cases, no only mutual exclusion(mutex) is needed, but also cooperation.

For example, the bounded consumer/producer problem: multi consumers and producers consume and send messages to a queue. Cooperation is needed cause the message queue has a max size, when the queue is full, no more messages can be sent, and when the queue is empty, no more messages can be consumed.

Below is the code showing the producer:

package monitor;

public class Producer {
    BoundedQueue queue;

    public Producer(BoundedQueue queue) {
        this.queue = queue;
    }

    public void send(int msg) throws InterruptedException {
        synchronized (queue) {
            // wait till there is room to produce
            while (queue.isFull()) {
                queue.wait();
            }

            // business logic here
            queue.add(msg);
            System.out.println("sent:" + msg + ", from:" + Thread.currentThread().getName());

            // before exit, call notify() to wake up waiting threads
            queue.notifyAll();
        }// implicit release the lock when exiting the synchronized block
    }
}

In the code, the BoundedQueue is used as a monitor, except for mutual exclusion, producers and consumers also need cooperation: when queue is full, producers need to wait(), and when queue has available slots, producers need to be notified to wake up from the wait, after producer send data to the queue, it also needs to call notifyAll() in case there are consumers waiting for the condition that the queue is not empty.

Here, the ability to wait and notify is provided by Monitor to make threads cooperate.

Hope this helps you understand the difference between Monitor and Lock.

Ref:

Hamrick answered 17/10, 2020 at 17:0 Comment(0)
S
0

In this document, you can find the answer to your question:

Synchronization. The Java programming language provides multiple mechanisms for communicating between threads. The most basic of these methods is synchronization, which is implemented using monitors. Each object in Java is associated with a monitor, which a thread can lock or unlock.

Searby answered 2/4, 2018 at 11:50 Comment(2)
It can be said that each object has a monitor, but the monitor is not useful when it does not synchronize, so it does not activate the call, which involves the monitor to monitor the data when the code is locked synchronously. Can this be understood in this way?Pontifical
This doesn't provide the definition of a lockHendry
H
0

A monitor is a combination of mutual exclusion, the ability to wait for an external condition to be true, and the ability to notify other threads of that event. The condition and notification pieces are essentially cooperation

A lock provides mutual exclusion. This means it prevents multiple threads from accessing the same data at the same time.

Notice a monitor uses mutual exclusion. Therefore, locks are used to implement monitors.

Hendry answered 23/3, 2021 at 0:3 Comment(0)
F
0

The other answers provide definitions of these two. Let's visualise a practical use case:

public class Test {

public synchronized static void testMonitor() throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("done");
}

public static void testLock(Object lock) throws InterruptedException {
    synchronized (lock){
    Thread.sleep(1000);
    System.out.println("done");}
}

public static void main(String[] args) throws InterruptedException {
    long start = System.currentTimeMillis();
    List<Thread> threadList = new ArrayList<>();
    for(int i=0 ;i< 10; i++){
        Thread thread = new Thread(() -> {
            try {
                Test.testMonitor();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadList.add(thread);
        thread.start();
    }

    for(int i=0 ;i< 10; i++){
        threadList.get(i).join();
    }
    long end = System.currentTimeMillis();
    System.out.println((end - start)/1000);

}

public static void main(String[] args) throws InterruptedException {
    long start = System.currentTimeMillis();
    List<Thread> threadList = new ArrayList<>();
    for(int i=0 ;i< 10; i++){
        Object lock = new Object();
        Thread thread = new Thread(() -> {
            try {
                Test.testLock(lock);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        threadList.add(thread);
        thread.start();
    }

    for(int i=0 ;i< 10; i++){
        threadList.get(i).join();
    }
    long end = System.currentTimeMillis();
    System.out.println((end - start)/1000);

}}

The first method testMonitor uses monitor(intrinsic lock). Running 1st main method will print execution time as 10 seconds.

The second method testLock uses object lock. Running 2nd main method will print execution time as 1 seconds.

Faenza answered 21/11, 2022 at 17:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.