How java object locking and monitor creation happens internally inside JVM
Asked Answered
G

1

9

Suppose I have following code snippet with two threads accessing same method with two critical sections (synchronized statements). Each of these synchronized statements is given a different lock object. Code as follows :

public class MyWorker {
private Random random = new Random();

private Object lock1 = new Object();
private Object lock2 = new Object();

private List<Integer> list1 = new ArrayList<>();
private List<Integer> list2 = new ArrayList<>();

private void stageOne() {

    synchronized (lock1) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        list1.add(random.nextInt(100));
    }

}

private void stageTwo() {

    synchronized (lock2) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        list2.add(random.nextInt(100));
    }

}

private void process() {
    for (int i=0; i<1000; i++) {
        stageOne();
        stageTwo();
    }

}

void main() {

    Thread t1 = new Thread(this::process);

    Thread t2 = new Thread(this::process);

    t1.start();
    t2.start();

    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

}

My question is not about an error in this code or how this executes in java stand point. This code works fine. I'm only taking this as a reference code so that the person who answers have a particular scenario to refer I want to know how JVM internally create monitor objects associated with this instance and how object locking happens internally according to this scenario using OpenJDK implementation. I am expecting a low level explanation.

I researched on this topic for couple of days and couldn't find an in depth explanation. These are some of my findings I went through :

  • This stackoverflow question Java lock concept how internally works?. But I couldn't find a thorough explanation within the answers.
  • JLS 17.1 provides an language explanation on how monitor works in high level, but not what "happens internally".

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. Only one thread at a time may hold a lock on a monitor. Any other threads attempting to lock that monitor are blocked until they can obtain a lock on that monitor. A thread t may lock a particular monitor multiple times; each unlock reverses the effect of one lock operation.

In the Java virtual machine, every object and class is logically associated with a monitor. For objects, the associated monitor protects the object's instance variables. For classes, the monitor protects the class's class variables. If an object has no instance variables, or a class has no class variables, the associated monitor protects no data.

To implement the mutual exclusion capability of monitors, the Java virtual machine associates a lock (sometimes called a mutex) with each object and class. A lock is like a privilege that only one thread can "own" at any one time. Threads need not obtain a lock to access instance or class variables. If a thread does obtain a lock, however, no other thread can obtain a lock on the same data until the thread that owns the lock releases it. (To "lock an object" is to acquire the monitor associated with that object.)

I know in instruction set level how monitorenter and monitorexit opcodes are used to manage synchronized statements. But I am trying to get a deeper understanding trough JVM source code level. But yet I'm struggling to map the OpenJDK source code with the high level explanations I found via above links since there is lot going under the hood in source code.

So can anyone who is familiar with OpenJDK source code give an explanation for following questions related to above code snippet using OpenJDK source code? I think ObjectMonitor, BasicLock, Synchronizer classes are more relevant to this explanation.

  1. For which object instance a monitor object is created? Is it for MyWorker object instance or Object lock1 or both? Because JSL and Bill Vennams explanations depicts that each object is associated with a monitor.
  2. If it's for MyWorker object instance how monitor is created for the MyWorker object instance?
  3. How lock object is created for the reference object Object lock1 we pass
  4. How actually monitor is locked by the lock object for a Thread?
Gravois answered 20/6, 2018 at 20:47 Comment(9)
I don't know, but I think the lock itself is accomplished with a test-and-set: en.wikipedia.org/wiki/Test-and-set These are popular machine instructions and I'm sure Intel implements one. If the test and set fails, then I think a check is made for owner and if it's the current thread, the monitor lock still succeeds. Otherwise the thread is blocked (or in some cases will spin wait).Crudden
Why is this question tagged with C++?Asmodeus
@Asmodeus Because I'm expecting an explanation through OpenJDK vm source code which is in C++Gravois
I do not think it is clear from the question. You might want to specifically ask to point to C++ code in JDK and explain that code.Asmodeus
You don't get the point. I have clearly specified this is about low level explanation of OpenJDK source code relevant to my reference java code, if you have a clear look. And that's why I referenced the source code files from OpenJDK and IMO C++ tag should be here.Gravois
@Insightcoder: Please edit the question and tag it with OpenJDKFredenburg
@Fredenburg Thanks. Done.Gravois
@Gravois question is still tagged with c++. I've sent an edit request.Omphale
Every object has a header associated with it, for 64 bits VM its 64 bits long. Some of those bits are resposible for locking.Faline
O
4

For which object instance a monitor object is created?

Every Java object is also a monitor object, including reflection objects, so your code has at least the following:

  • Class object for MyWorker
  • Class object for Random
  • Class object for Object
  • Class object for List
  • Class object for Integer
  • Class object for ArrayList
  • ... and many more ...
  • Random instance assigned to field random
  • Object instance assigned to field lock1
  • Object instance assigned to field lock2
  • ArrayList instance assigned to field list1
  • ArrayList instance assigned to field list2
  • Thread instance assigned to local variable t1
  • Thread instance assigned to local variable t2
  • Every Integer instance created by auto-boxing when calling add(random.nextInt(100))

Is it for MyWorker object instance or Object lock1 or both?

Both

If it's for MyWorker object instance how monitor is created for the MyWorker object instance?
How lock object is created for the reference object Object lock1 we pass
How actually monitor is locked by the lock object for a Thread?

Depends on JVM internals. There is no single answer to this, and a "thorough explanation" is beyond the scope of this site.

Ocher answered 20/6, 2018 at 21:0 Comment(17)
Can you give me an explanation on HotSpot JVM implementation?Gravois
@Ocher your direct way of communication appeals to me.Asmodeus
@Gravois Explanation of what specifically? I'm sorry, I don't know what "how" you're looking for. --- How monitors work down at the CPU level? That is a generic low-level question that has nothing at all to do with Java.Ocher
Yeah, exactly this is a generic low-level question that has nothing at all to do with Java. That's why I have mentioned in the question that "My question is not about an error in this code or how this executes." I only took Java code only as a reference so that low level execution can be explained with regard to that. And I have specifically asked the help of one who has the experience with OpenJDK source code. But it seems like all the upvoters for "No" answer even don't understand this question is all about a low level explanation for the particular java code.Gravois
@Gravois since you asked a dozen questions at once, you should not blame the answerer for addressing 90% of them but missing your actual question. If your actual questions is how the JVM implements locking on the lowest level, then 90% of your question text is obsolete noise.Breaking
@Breaking I didn't put any blame on the answerer. Actually he is the only one who is decent and helpful enough to help me in what ever he can rather than the guys who yell here even without understand the question and try to give an actual explanation.Gravois
@Gravois you just did it again. You said “the guys who yell here even without understand the question” instead of “the guys who did not understand the one of my dozen questions”. The problem is, that one question is way to broad for Stackoverflow, even with an asker who understands the matter. But you combined it with several other questions indicating that you lack understanding of even the basics. You want an explanation of the C++ code with reference to an example Java code that you posted with your question. That doesn’t make any sense.Breaking
@Breaking I put that question here after doing a thorough research and after I understood the basics. All I understood can't be explained here. To get a deeper level of understanding since I'm so curious I put this. If it doesn't make it sense to you that's fine. Please answer the question if you can or don't drag unwanted conversation here that doesn't make any value.Gravois
If you understood the basics, you didn’t ask “For which object instance a monitor object is created?” And again, stop saying “the” question when you asked a dozen questions. Most of them have been answered by Andreas. The others are, as already said, way too broad. I already flagged your question(s) as too broad, that’s all I can do for you.Breaking
@Breaking I know each object associated with a monitor. As I have mentioned in the question itself I went through Bill Venners' explanation, JSL and dozen of other resources and perfectly understood that an monitor object is created in conceptual level. But if you go through the OpenJDK source code there is no such one to one mapping from so called Java "monitor" object to C++ "monitor" object. I wanted to know how that is implemented inside C++ in JVM level how that mapping happens.Gravois
@Gravois if you can’t read, it doesn’t help to say “explain me reading using Shakespeare’s work”. You still can’t read and ask about something that is over your head. Perhaps it helps to first understand that there is no such thing as a “Java monitor object”. Every Java object has an associated monitor. The monitor is not an object. There are different ways to implement a monitor and the HotSpot JVM implements at least three of them, which are used depending on runtime options and heuristics. Explaining C++ code “related to above [Java] code snippet” still makes no sense at all.Breaking
@Breaking Let me emphasis you one this last time. I asked all 4 questions after I clearly mentioned "So can anyone who is familiar with OpenJDK source code give an explanation for following questions related to above code snippet using OpenJDK source code" Because I partially grabbed how it is implemented by reading JVM source code. This question may not be too broad to contributors in OpenJDK. I targeted them specifically mentioning "anyone who is familiar with OpenJDK source code". That's all.Gravois
@Breaking I know that there is no such object as Java monitor object which is a subclass of Object class. It is pretty obvious why Java didn't expose such an object, because all synchronization stuffs handles by Java itself abstracting out it implementation. What I meant here was how "conceptual java monitor" is implemented inside JVM. That's where I got stuck and asked for help from an expert of OpenJDK. And it's not like “explain me reading using Shakespeare’s work”Gravois
@Gravois you are right, your question is well crafted, reasonable and exhibiting your good understanding of the matter which just needs that small explanation to be completed and we are all just too stupid to understand your question. Good luck waiting for the JDK developers to show up and explain the entire C++ code to you.Breaking
@Breaking If I had small explanation to be completed in first place I wouldn't have asked such a long question here. If you say you are stupid that's none of my business and I didn't say that and disrespect either you or anyone here. Who asked for an entire C++ code explanation here? That's why I told, you are missing my point. I wanted an explanation of how it's built inside JVM conceptually and I'm not the only one who is waiting for such an explanation. You can see that there are other stackoverflow users waiting for such an explanation.Gravois
@Gravois you have emphasized multiple times that you want an explanation of the C++ code, e.g. “I'm expecting an explanation through OpenJDK vm source code which is in C++”, or “I wanted to know how that is implemented inside C++ in JVM level”. It was me who said that you lack conceptual knowledge. And you did claim that other people do not understand your question. There’s nothing more to say.Breaking
@Breaking Yeah I emphasized that i want an explanation through JVM source code how its implemented inside JVM and that's still my requirement. But it doesn't mean "explain the entire C++ code". There’s nothing more to say.Gravois

© 2022 - 2024 — McMap. All rights reserved.