• 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
  • Paul Clapham
  • Ron McLeod
  • Jeanne Boyarsky
  • Tim Cooke
Sheriffs:
  • Liutauras Vilda
  • paul wheaton
  • Henry Wong
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Frits Walraven
Bartenders:
  • Piet Souris
  • Himai Minh

synchronized on a variable

 
Ranch Hand
Posts: 155
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator



Does the    synchronized(Integer.toInt(number)) achieve the supposed synchronization effect on variable "number" ?
 
Master Rancher
Posts: 4196
57
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Linwood Hayes wrote:Does the    synchronized(Integer.toInt(number)) achieve the supposed synchronization effect on variable "number" ?



Well, there's no method Integer.toInt(), so we would have to guess what it does.  I have a few different guesses which would lead to different results.  I suggest you try compiling the code to see if it is even allowed, then let us know what you mean to ask about.
 
Linwood Hayes
Ranch Hand
Posts: 155
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:

Linwood Hayes wrote:Does the    synchronized(Integer.valueOf(number)) achieve the supposed synchronization effect on variable "number" ?



Well, there's no method Integer.toInt(), so we would have to guess what it does.  I have a few different guesses which would lead to different results.  I suggest you try compiling the code to see if it is even allowed, then let us know what you mean to ask about.



sorry, I didn't think when I typed..  have corrected it in the code.  it is "valueOf()"
 
Mike Simmons
Master Rancher
Posts: 4196
57
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
OK.  So it returns an Integer, while the original variable number was an int.  On one level, yes it is possible to synchronize on Integer.valueOf(number).  But that's not the same thing as synchronizing on number, which is a different type, and not possible to synchronize on because it's not an Object.

Regardless, it's a bad idea for a few different reasons.  One is that I can't even tell what the goal would be for synchronizing like this.  Another is that we don't know whether valueOf() will return a shared cached instance, or a unique value.  So it's hard to predict what effect this will have.  And also because code really shouldn't synchronize on any object it doesn't own or control in some sense... because just about any library out there could have access to the same Integer instances that we do, and if that code also synchronizes on those instances, it can create deadlock.  Don't synchronize on an object that you don't know where it came from.
 
Linwood Hayes
Ranch Hand
Posts: 155
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you for the input
 
Sheriff
Posts: 22649
126
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Synchronizing on the result of Integer.valueOf (and valueOf methods in the other numeric wrappers) has one of two results:

1) If the value is in the cache (by default: -128 to 127; for Integer this can be extended with a system property), then you synchronize on the value that is used all over the place. It's not "your" value. This can lead to several issues, including deadlock (due to lock ordering, which you cannot control because everybody can synchronize on the value).
2) If the value is not in the cache, you synchronize on a newly created object. The synchronization is senseless, and the JVM (or even the compiler) may omit the synchronization completely.

If you need to synchronize on a primitive field, you need a separate lock for that. It can be an existing field, or a completely new field (e.g. private final Object numberLock = new Object();). Or, if possible, don't use int but AtomicInteger instead, if the field does not take part in any invariant that involves other fields. If it does, you need to use one single lock for updating all these fields anyway.
 
Marshal
Posts: 75707
354
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you are using locks, wouldn't you want to use an explicit lock object? Try the java.util.concurrent.locks package.It is possible to lock the same Lock repeatedly as long as it is unlocked every time it is used. There are also other kinds of Lock.
 
Rob Spoor
Sheriff
Posts: 22649
126
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It depends on your needs. I recently re-read Java Concurrency in Practice, and it doesn't say you should drop all intrinsic locks. It even states that it's sometimes the best solution.

If all locking and unlocking is done as part of the same block like your example, and I only have one condition, I prefer intrinsic locks over ReentrantLock because I don't have to add all the try-finally overhead. As soon as I have multiple conditions, or I need to use more complex flows for lock+unlock (for whatever reason, it hasn't happened so far fortunately), then Reentrantock is the way to go for me.
 
Linwood Hayes
Ranch Hand
Posts: 155
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What if

in this case, regardless of whether it is a good practice, such synchronization functions on the "number" var, right ?
 
Rob Spoor
Sheriff
Posts: 22649
126
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, but unfortunately, the synchronizing is done on different objects. When you do number += ..., what actually happens is this:

That means that you get the same issue as synchronizing on Integer.valueOf(number) - it still isn't "your" object. If this is your case, I suggest using AtomicInteger instead:

You can also use getAndUpdate; the difference is in whether you get the old (getAndUpdate) or new (updateAndGet) value. To prevent the notorious check-then-act issue, where the value can have changed after the checking, the check is moved to inside the updating.

Come to think of it, because you only add a value if the current value is 2, you can use compareAndSet:
 
Rob Spoor
Sheriff
Posts: 22649
126
Eclipse IDE Spring VI Editor Chrome Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Come to think about it some more, the synchronization on series is also wrong. Again, you switch the objects you synchronize on. And again, it's not necessarily "your" object. The string may be a constant like "hello", which means it comes from the string pool. That in turn means that every other use of the same constant can synchronize on the same object, with the same problems described earlier.

In this case:
  • synchronize on this
  • or introduce a new (private final) lock field
  • or use an AtomicReference<String>
  •  
    Mike Simmons
    Master Rancher
    Posts: 4196
    57
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Well, with "series", we have no idea how or if it's being initialized.  As written, it's not assigned to until after the JVM attempts to synchronize on it.  Which will result in a NullPointerException since it's null.  
     
    What's that smell? Hey, sniff this tiny ad:
    free, earth-friendly heat - a kickstarter for putting coin in your pocket while saving the earth
    https://coderanch.com/t/751654/free-earth-friendly-heat-kickstarter
    reply
      Bookmark Topic Watch Topic
    • New Topic