• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Please help me understand this small piece of code

 
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi All,

I was reading through synchronized statements but could not understand this implementation:




Can anyone explain its working?

Thanks in advance.

Tushar
 
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Tushar, welcome to Java Ranch!

First, please use code tags when posting code samples. They make it much easier to read. I've added them for you here.

The class has methods for incrementing c1 and c2, and these are synchronized so that multiple threads could use the same MsLunch object and not corrupt the counters (i.e. c1 and c2). I think c++ is an atomic operation, so the synchronization may not be necessary, but think if it was c = c + 1. That could be implemented by the JVM as:


RETRIEVE C from memory
ADD 1 to C
STORE result back to memory

Remember a thread can be interrupted any time, even in the middle of an operation. Let's say two threads called it at the same time, and one was interrupted in this process.

T1: RETRIEVE C from memory
T2: RETRIEVE C from memory
T2: ADD 1 to C
T2: STORE result back to memory
T1: ADD 1 to C
T1: STORE result back to memory

The net result is C has been incremented by 1, but it should have been incremented by 2.

By synchronizing the code, we tell thread 1 to get the "monitor" of the object synchronizing the block of code (i.e., lock1 or lock2) before it can enter that block. It's only important to remember that every object has a monitor, and that only one thread at a time can have it. If thread 1 is interrupted before it completes the synchronized block, then it keeps the monitor while it waits for its next turn to execute. When thread 2 wants to enter the synchronized block, it tries to get the monitor, but can't since thread 1 already has it, so thread 2 has to wait. Eventually thread 1 gets some more execution time, finishes the synchronized block, and releases the monitor. The next time thread 2 can execute, it will be able to get the monitor and enter the block.
 
Tushar Kush
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot greg for such a clear explaiantion.

First of all sorry for not using code tags as this was my first post on java ranch,i just joined.

I have one more doubt like how will thread 1 will acquire lock on objects lock1/lock2.


thanks,
Tushar
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The objects lock1/lock2 aren't locked, despite their names. They just control access to the synchronized blocks of code. Imagine the monitor as a key to a door. Each object lock1 and lock2 has one of these keys. (The object you make by calling new MsLunch() also has one, though in this example nothing is asking for it.) OK, now think of synchronized blocks as rooms with locked doors, and threads as people who want to get through those doors. Mr. Thread1 comes to the locked door of the synchronized block in incl(), and sees that the key (monitor) belongs to lock1. He goes to the JVM, asks to borrow the key, uses it to open the door, goes into the room, and the door locks behind him. While he's in there, Ms. Thread2 goes to the same door, finds it locked, and goes to the JVM to ask for the key. The JVM says, sorry, someone's using it, you'll have to wait. Mr. Thread1 finishes his work in the block and returns the key. The next time Ms. Thread2 asks for the key, the JVM finds it's been returned and hands it over to her so she can get into the room.

Problems that Mr. Thread1 and Ms. Thread2 run into are exactly what you have to watch out for in synchronization. One problem is that after Thread1 returns the monitor, Thread3 may swoop in and grab it before Thread2 gets a chance. If that happens too often, then it's called starvation. The JVM tries to prevent thread starvation, but it can be a difficult problem. Another problem is deadlock, which is mostly up to the programer to prevent. Some tasks may require having two keys simultaneously to accomplish. If Thread1 has one key, but has to wait for the second, while at the same time Thread2 has the second and has to wait for the first, they will both have to wait forever.
 
Tushar Kush
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok ,that clearified the concept more...

If I want to write the code for the two threads to approach the inc1 method will it be like below:




we are not explicitly using Object lock1 any where in the code which provides monitor for the sync method inc1()?

m not sure if this code will compile ,just wrote to expresss my approach in understanding synchronization...

Thanks,
Tushar
 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There's no need to sleep to release a monitor. It will be automatically released when the thread finishes running the statements in the synchronized block. Also keep in mind that there is one monitor per instance. m2 and m11 in your example are two different instances of MsLunch, and each one has its own instances of lock1 and lock2. That makes four total monitors. Your main thread and Thread2 could both be inside the synchronized block of inc1() at the same time, but it doesn't matter because they are working on different fields. The main thread increments the c1 field of the m11 instance and Thread2 increments the c1 field of the m2 instance.
 
Tushar Kush
Greenhorn
Posts: 6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok...It is clear to me now...

Thanks Greg for your precious time and help..

 
Greg Charles
Sheriff
Posts: 3063
12
Mac IntelliJ IDE Python VI Editor Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You're welcome!
 
Get me the mayor's office! I need to tell him about this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic