• Post Reply Bookmark Topic Watch Topic
  • New Topic

Help Understanding Method Access during Parallel Execution  RSS feed

 
Jamie Patrick
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi there, this is something Im still trying to get my head around so if anyone can help my small brain get it then thanks.
Its not a question about thread-safety, rather about understanding how method code is shared by threads.


Imagine my very simple class:

Assume that as part of the implementation no synchronized (or other locking code) is encountered.





Imagine a machine with 10 cores and 10 threads running in parallel - 1 on each core.

There is 1 instance of SimpleClass in the shared Heap memory on this machine - lets say its a Singleton or some other global object that somehow all the 10 threads have access to - these details are unimportant for my question.


Scenario 1 - all 10 threads want to run through staticMethod() at the same time (by pure theoretical coincidence)


Q. Can all 10 threads theoretically enter/exit the staticMethod() at the same time? Or, more generally, they do not interfere with each other at all?

Since there is no locking (of the class) going on I think they can but just want confirmation.


Scenario 2 - all 10 threads want to run through instanceMethod() at the same time (by pure theoretical coincidence)


Q. Can all 10 threads theoretically enter/exit the instance method at the same time?


Again, since there is no locking (of the object) going on I think they can but just want confirmation.


-----------------------------------------------------------------------------------------------
If the above 2 methods were synchronized then I understand that the threads cannot execute in parallel since they have to sequentially obtain/release the lock.
But the non-synchronized scenario is more difficult for me for some reason since I got confused I think by the fact that regardless the number of instances, there is only 1 copy of the method code (and other class constructs) in metaspace (or PermGen if you are not on Java 8 yet).
So I got confused thinking that single copy of the method code in non-heap space would still present a restriction whereas my understanding is that each thread would (logically) have its own 'copy' of all method code, regardless of whether it is static or instance.



 
Henry Wong
author
Sheriff
Posts: 23295
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It has been many years since people coded in assembly, and wrote self-modifying code, so I think it is safe to say that code is (generally) read-only -- and it is definitely true for Java byte code. Hence, the methods can be shared among threads.

Henry
 
Campbell Ritchie
Marshal
Posts: 56530
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

Please make sure to indent your code; I shall go back and indent it for you this time.
 
Jamie Patrick
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cheers Ritchie - will make sure I indent next time.

Henry, thanks for your reply - my interpretation of your comment was that the threads CAN all theoretically enter/exit both the instance/static methods on the same object in parallel?

Thanks
James
 
Campbell Ritchie
Marshal
Posts: 56530
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I think that is right. I think you get separate call stacks so you will have duplicates of all local variables. You also get the bytecode executed onto its stack by each of the threads.
If the static method doesn't modify any fields, then I think you won't have any synchronisation problems. At least I think not. I am not sure.

If the instance method modifies a field, then you can call that method in as many threads as you like. But there is no guarantee that the field will be modified in any particular order. Even worse there are three places (if not more) where those values are stored:
  • 1: in registers on the chip
  • 2: In cache memory
  • 3: In RAM (the object on the heap)
  • So you don't know which of those will be updated by which thread, making things even more complicated. You can simplify that slightly by marking the field volatile, which reduces the number of places stored to “on the heap”, but even that won't make the threads call the method in any particular order.
    So whenever you are modifying a field in a method and that isn't “atomic”, you get the threads interfering with one another like nobody's business.
     
    Jamie Patrick
    Greenhorn
    Posts: 5
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Campbell,

    Thanks for the comments. I wanted to just get a grasp of how multiple threads are allowed to run through a non-locked method in parallel.

    I was trying to get my head around whether a Singleton (concurrency/parallelism issues to one side) causes any performance constraints i.e. I got it in my head somehow that it imposed a performance constraint on multiple threads somehow because they wouldn't all be allowed to access the same method code at the same time. But of course as you guys point out - they all get to run the byte code in their separate stacks, and its only when some locking mechanism comes into play that there might be any access constraints - and therefore any performance constraints.

    However, your comments on thread-safety are very welcome.

    -------------------------------------------------------------------------------

    On that note, my understanding of Volatile is that it ensures that no values are cached thread-locally, but I didn't really grasp this to well to be honest.

    To quote the JLS:

    The language specification guarantees that reading or writing a variable is atomic unless the variable is of type long or double [JLS, 17.4.7].


    I have the following beliefs now regarding Volatile - i would very much appreciate it if you (or anyone else) can confirm/disprove please:-

  • we only need to worry about long and double assigment on 32 bit systems - since assignment on 64 bit systems will be a single operation ??
  • Volatile is some locking mechanism which means that no other thread can read/write to main memory if one thread is already reading/writing a volatile value (primitive) ??
  • We don't need to worry about anything on the stack since this is thread-local ??


  • If point 2 above (locking) is not correct, then Im not sure how Volatile brings about thread-safety even if any values in CPU Registers or CPU cache are flushed immediately to main memory because this still leaves opportunity for other threads to see intermediate values right?

    Thanks
    Jamie
     
    Campbell Ritchie
    Marshal
    Posts: 56530
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jamie Patrick wrote: . . .
    On that note, my understanding of Volatile is that it ensures that no values are cached thread-locally, but I didn't really grasp this to well to be honest.
    You don't get thread‑local caching. Threads are software, caches are hardware. If you have the same number of threads as cores, how do you know that each thread runs on a different core? A volatile (not Volatile) value must have the result flushed from registers and cache onto the heap. Similarly it must be read from the heap not from cache or registers.
    . . .
    I have the following beliefs now regarding Volatile - i would very much appreciate it if you (or anyone else) can confirm/disprove please:-

  • we only need to worry about long and double assignment on 32 bit systems - since assignment on 64 bit systems will be a single operation ??
  • Very dangerous assumption to make. Unless the JLS changes to specify behaviour on 64‑bit machines, you cannot know about that. You have to assume that double assignment is not atomic even on a 64‑bit machine.
    Also that rule only applies to a single assignment
    String s = "Jamie Patrick";
    If you have something more complicated it ceases to be atomic
    String s = myForumUser.getName();

    The chances of different behaviour on different machines are slim, since Java® has always advertised itself as platform‑neutral.
  • Volatile is some locking mechanism which means that no other thread can read/write to main memory if one thread is already reading/writing a volatile value (primitive) ??
  • No, volatile variables are not locked. It specifies where their values are read in memory.

  • We don't need to worry about anything on the stack since this is thread-local ??
  • I think that local variables are unaffected by threading. But I am not sure.

    Anyway, it is usually object state you are worried about, which depends on fields, so you aren't going to worry about local variables.
    If point 2 above (locking) is not correct, then Im not sure how Volatile brings about thread-safety even if any values in CPU Registers or CPU cache are flushed immediately to main memory because this still leaves opportunity for other threads to see intermediate values right?

    Thanks
    Jamie
    You're welcome

    The contribution the keyword volatile makes to thread safety is minor.
     
    Campbell Ritchie
    Marshal
    Posts: 56530
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You can have method1 operate on a variable, then the JVM “knows” that method2 is about to operate on the same variable. So it is permitted to retain that value in a register or a cache because execution is much quicker like that.
    If you are multi‑threading, how will a thread “know” whether the value in the register or that in the cache or that in the RAM (heap) is the most recent version?
     
    Martin Vajsar
    Sheriff
    Posts: 3752
    62
    Chrome Netbeans IDE Oracle
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jamie Patrick wrote:
  • we only need to worry about long and double assigment on 32 bit systems - since assignment on 64 bit systems will be a single operation ??

  • It might be true, but the specification doesn't say so, so all bets are off. I would expect that a 64-bit system uses 64-bit instruction for it, but it isn't guaranteed.

    Declaring it volatile guarantees consistency everywhere, so this is what I would do if the consistency was important.

  • Volatile is some locking mechanism which means that no other thread can read/write to main memory if one thread is already reading/writing a volatile value (primitive) ??

  • Yes, volatile provides some syncing/locking mechanism.

    As I understand the specification, it guarantees that reads occurring after a volatile variable was written will read the written value. I think that volatile variable can be read by several threads simultaneously. I'm not sure about simultaneous writes. Volatile isn't very useful mechanism to solve possible concurrent writes, though, because you don't know (have no guarantees) in which order the threads will write the value. So, if the order of writes is important, you'll have to use a more sophisticated mechanism.

  • We don't need to worry about anything on the stack since this is thread-local ??

  • Absolutely. Each thread is assigned its own stack; if a variable is on stack, it can't be accessed by other threads.

    Remember, though, that objects are stored on the heap, and if several threads have local variables referencing the same object, they need to sync their access to the object (unless the object is immutable).

    If an object is created by a thread and a reference to it is stored on the stack only, it can't be accesses by other threads, so it is thread-safe (actually if the object uses static variables and doesn't synchronize them properly, this won't be true; so only use properly designed classes).
     
    Jamie Patrick
    Greenhorn
    Posts: 5
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell, thanks for giving me so much information - it is very much appreciated.

    Martin, likewise, thanks for your comments.

    It has really helped me out.
     
    Campbell Ritchie
    Marshal
    Posts: 56530
    172
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You're welcome Glad to be of use.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!