• 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 explain synchronization logic in this example

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

Does somebody know why in the following code k2 can be greater than k1? (a sample output: k1: 365731 k2: 365898). Example is a revised version of Mughal book question 13.13.

Thanks,


 
Ranch Hand
Posts: 924
1
Netbeans IDE Fedora Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
i'm not sure but i will try to answer your question. i think this is happening because of thread cache. you might want to read more about it on the net. after having a second look at your code i think thread cache might not be the problem. i got confused with the critical section. earlier though that two threads will be accessing the static variables simulataneosly but since you have acquired lock on object of the class Class, i think only one thread will be able to enter the guarded region and the other thread will be blocked. though this may not be the answer to your question, i get a chance to refresh my memory.

 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
try this ;) . and what you observed?
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

gurpeet singh wrote:i i think this is happening because of thread cache.


true... unfortunately it is not guaranteed the cache of both k1 and k2.... (correct me if i am wrong ) . I am not that much involving in thread related techniques in real time
 
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

T. Adams wrote:Hi,

Does somebody know why in the following code k2 can be greater than k1? (a sample output: k1: 365731 k2: 365898). Example is a revised version of Mughal book question 13.13.

Thanks,



Theoretically, k1 should be equal to k2 all the time.
But when thread 1 increases k1, it has the following three steps underneath the hood.
1. int temp1 = k1
2. temp1=temp+1;
3. k1 = temp1.
where temp is the temporary memory location for the value of k1.
The same steps will work for k2:
1. int temp2 = k2
2. temp2=temp2+1;
3. k2= temp2.


Consider this:
0. k1=0; k2=0
1. Thread 1 is in the middle of step 2 for k1 when it exist the synchronize block. Thread 1 just assigns temp1 = 1. k1 is still zero, not has been updated yet.But k2 has been assigned 1 already.
3. Check the condition k1<k2, it exits.

This is just my idea. It can be wrong.
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think helen ma post seems to be interesting... so my question is that cpu scheduler can take thread out from synchronized block ?
 
Ranch Hand
Posts: 256
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Golden rule of synchronization : It is not enough just to synchronize the writes, you need to synchronize the READs too.
 
Helen Ma
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Seetharaman Venkatasamy wrote:I think helen ma post seems to be interesting... so my question is that cpu scheduler can take thread out from synchronized block ?


Hi, Seetharaman.
I am not sure if my guess is correct.
When thread 1 is running the synchronized block, in theory, no other threads can access that block. In theory, k1 should be always equal to K2.
But, when I ran this code posted by Adam, there is a chance that K2> K1.
 
Ranch Hand
Posts: 187
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator



Please correct if i am wrong...
 
Helen Ma
Ranch Hand
Posts: 451
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi, Gauranghumar,
When thread 1 and 2 are comparing k1 and k2, k1 and k2 are the two variables shared by them. It's because K1 and k2 are static instances of the class. So, in theory, thread 1 and thread 2 are "looking at" the same data.
How can this happen "thread 1 and thread 2 will do an unsynchronized comparision and got k2> k1"?
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Helen Ma wrote: thread 1 and 2 are comparing k1 and k2, k1 and k2 are the two variables shared by them. It's because K1 and k2 are static instances of the class. So, in theory, thread 1 and thread 2 are "looking at" the same data.
How can this happen "thread 1 and thread 2 will do an unsynchronized comparision and got k2> k1"?



Let me put my understanding[or story ]:

*the key is that even static variables can be cached by threads. * - to make execution faster; and probably it can be load from main memory some time.

and now let say threadA enter synchronized block, made k1++ and k2++, (then it compares k1 and k2 )now when it loads k1 from main memory. scheduler put threadA on wait, now threadB started and running some more time now probably k1 and k2 values increased, after some time scheduler hold threadB and strats threadA- it alread loads k1 and keeps in cache now it loads k2 from memory obviously k2 is greater than k1. hence the result.
 
Ranch Hand
Posts: 201
1
Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
this is a very strange program. it is surprising to see the k2 is updated before k1 when k2 is after k1 in the synchronized block of the code. Maybe, since thread behavior is so unpredictable, one thread increments one static variable then is stopped for some reason and the other thread grabs the monitor and increments k2... Or maybe something else happens that I can barely comprehend with my tiny reptile brain. threads are humbling, like looking at a photo of the milky-way galaxy and seeing earth is just an unseen pixel circling some random star also represented by a pixel or two in the photo.

Does the author of the book give any logical explanation for this?
 
Gaurangkumar Khalasi
Ranch Hand
Posts: 187
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Helen Ma wrote:Hi, Gauranghumar,
When thread 1 and 2 are comparing k1 and k2, k1 and k2 are the two variables shared by them. It's because K1 and k2 are static instances of the class. So, in theory, thread 1 and thread 2 are "looking at" the same data.
How can this happen "thread 1 and thread 2 will do an unsynchronized comparision and got k2> k1"?



Thank you for a reply...

yes they are "looking at the same data".

I want to tell that there is a synchronized block in which increment operations k1++; and k2++; will be done by either Thread1 or Thread2, only one at a time.

The rest code in that function is not synchronized(i.e. unsynchronized... ), so think like the below :

1)Both threads able to get the entry into the "run" method simultaneously (Because it is not synchronized or not locked by any thread).
2) Now assume that Thread1 will go from the "Runnable" state to "Running" state before Thread2.
3) In that case Thread1 will enter first in the Synchronized block and will increment both k1 and k2
and also during that operation if Thread2 will get "Running" state but it has to wait for Thread1 to complete its task than and than it will get entry into Synchronized block.
4) After the completion of Thread1, Thread2 get the entry into the Synchronized block and
as per my previous post the sequence of operations in the Synchronized block may be get changed for code optimization by compilers (or may be by microprocessors).
So i assume that Thread2 will get first statement to execute is k2++.
5) Now during that execution by Thread2, Thread1 will free to do its operation ahead and it will try to check k2>k1 and
because Thread2 has only incremented k2 (and after it, it will get turn for k1 also (but currently it has not done)), so at this stage k2>k1; and we will get the result.
 
Greenhorn
Posts: 15
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[quote=Seetharaman Venkatasamy

Let me put my understanding or story :

*the key is that even static variables can be cached by threads. * - to make execution faster; and probably it can be load from main memory some time.

and now let say threadA enter synchronized block, made k1++ and k2++, (then it compares k1 and k2 )now when it loads k1 from main memory. scheduler put threadA on wait, now threadB started and running some more time now probably k1 and k2 values increased, after some time scheduler hold threadB and strats threadA- it alread loads k1 and keeps in cache now it loads k2 from memory obviously k2 is greater than k1. hence the result.



Hi Seetharam,

I tried marking the variables k1 and k2 volatile. Still it produces the same result.
Since the variables are marked volatile they should be reconciled with the original copy before they are used. So in that case during the compassion the latest values of the variables should be used.
Please correct me if I am wrong.

 
Ted North
Ranch Hand
Posts: 201
1
Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
https://coderanch.com/t/584617/java-programmer-SCJP/certification/understand-synchronized-logic-example-java

the posts on this thread are helpful

tl:dr - threads are crazy and stop and start wherever they like and that is why bogus stuff is happening

a solution maybe to make more of the program synchronized so that the operation is atomic. Seetharaman did this with including the if test in the synchronized code.

This is quite a mind-bending program!

 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
from what Ted given:
Matthew response:


The key point is that only the synchronized block is protected. As long as one thread isn't blocked, there's the possibility of control passing between them at any time.



This means, even scheduler can holds a thread which is inside synchronized block, and can pass control to other thread which is out side synchronized block.

quite interesting. I had an opinion is that scheduler keep an running a thread until it finishes the synchronized block. let me test some sample program and then post the result.
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I have talked with my ex-team lead who worked lot in jgroup/thread related stuff when i was with him.
his reply to this thread.


Hey I checked your mail
Independent statements within synchronized blocks can anytime be reordered by JIT
This is done for performance optimization
Please refer statement reordering in Java
So even if you add a system.out printing both variables inside the synchronized block will create dependency and eliminate statement reordering....
Thats the reason when there is a relation b/w variables accessed by multiple threads both read & writes should be synchronized

read this:http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#8.3.1.4
Also look at happens-before in hava



Thanks to him
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
correct behavior:
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic