synchronization token in Groovy

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

synchronization token in Groovy

Hamlet D'Arcy
Hi All, I have a Groovy concurrency question and thought someone here
might help.

In Java, you should not synchronize on boxed primitives:
class A {
  final Integer lock = 5;
  void method() {
    synchronized(lock) { ... }    // BAD!
  }
}

Since Integer objects can be cached and shared, this code could be
synchronizing on the same object as other, unrelated code, leading to
unresponsiveness and possible deadlock. There is a whole SO thread to
read if you want:
http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value

It's unsafe in Java to sync on Byte, Short, Integer, Long, Float,
Double, Boolean, and Char.

I assume in Groovy it is unsafe to sync on byte, short, integer, long,
float, double, boolean, and char primitive types. Is that correct?

Now how does type promotion play with synchronization... Assuming you
sync on a final field, then it is OK to sync on a final BigInteger or
BigDecimal because these fields are final. Is that correct as well?

Thanks,

--
Hamlet D'Arcy
[hidden email]

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: synchronization token in Groovy

Alex Tkachman
The rules are simple:

1) there is no real way to sync on primitive in JVM Only on objects

2) This is absolutely OK to sync on instances of any type as long as
the instance is "unique" in the sense. So your code below is 100%
legal but it is wrong in a sense that
some other guy could decide to sync on another instance of Integer
representing number 5 but compiler or JRE or JVM will optimize it in a
way that you will share the same instance.  This is reason why you
never should synchronize on strings (even synchronization on interned
ones is not the best idea).

class A {
  final Integer lock = 5;
  void method() {
   synchronized(lock) { ... }    // BAD!
 }
}

3) Best practice I think is always sync on specially allocated new
Object(), which created once in constructor, kept in private field and
never changed. Or to know for sure  (which is usually not possible)
what gonna happen if you synchronize on this. Normally it is good way
to deadlock :)

My personal belief is "avoid synchronized if you can and see what you
are doing wrongly if you can not"

On Tue, Feb 1, 2011 at 8:23 PM, Hamlet D'Arcy <[hidden email]> wrote:

> Hi All, I have a Groovy concurrency question and thought someone here
> might help.
>
> In Java, you should not synchronize on boxed primitives:
> class A {
>  final Integer lock = 5;
>  void method() {
>    synchronized(lock) { ... }    // BAD!
>  }
> }
>
> Since Integer objects can be cached and shared, this code could be
> synchronizing on the same object as other, unrelated code, leading to
> unresponsiveness and possible deadlock. There is a whole SO thread to
> read if you want:
> http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value
>
> It's unsafe in Java to sync on Byte, Short, Integer, Long, Float,
> Double, Boolean, and Char.
>
> I assume in Groovy it is unsafe to sync on byte, short, integer, long,
> float, double, boolean, and char primitive types. Is that correct?
>
> Now how does type promotion play with synchronization... Assuming you
> sync on a final field, then it is OK to sync on a final BigInteger or
> BigDecimal because these fields are final. Is that correct as well?
>
> Thanks,
>
> --
> Hamlet D'Arcy
> [hidden email]
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: synchronization token in Groovy

Hamlet D'Arcy
Thanks Alex, that was my understanding too.

And if your class is Serializable... don't sync on new Object() but
instead new Object[0].


--
Hamlet D'Arcy
[hidden email]


On Tue, Feb 1, 2011 at 7:44 PM, Alex Tkachman <[hidden email]> wrote:

> The rules are simple:
>
> 1) there is no real way to sync on primitive in JVM Only on objects
>
> 2) This is absolutely OK to sync on instances of any type as long as
> the instance is "unique" in the sense. So your code below is 100%
> legal but it is wrong in a sense that
> some other guy could decide to sync on another instance of Integer
> representing number 5 but compiler or JRE or JVM will optimize it in a
> way that you will share the same instance.  This is reason why you
> never should synchronize on strings (even synchronization on interned
> ones is not the best idea).
>
> class A {
>   final Integer lock = 5;
>   void method() {
>    synchronized(lock) { ... }    // BAD!
>  }
> }
>
> 3) Best practice I think is always sync on specially allocated new
> Object(), which created once in constructor, kept in private field and
> never changed. Or to know for sure  (which is usually not possible)
> what gonna happen if you synchronize on this. Normally it is good way
> to deadlock :)
>
> My personal belief is "avoid synchronized if you can and see what you
> are doing wrongly if you can not"
>
> On Tue, Feb 1, 2011 at 8:23 PM, Hamlet D'Arcy <[hidden email]> wrote:
>> Hi All, I have a Groovy concurrency question and thought someone here
>> might help.
>>
>> In Java, you should not synchronize on boxed primitives:
>> class A {
>>  final Integer lock = 5;
>>  void method() {
>>    synchronized(lock) { ... }    // BAD!
>>  }
>> }
>>
>> Since Integer objects can be cached and shared, this code could be
>> synchronizing on the same object as other, unrelated code, leading to
>> unresponsiveness and possible deadlock. There is a whole SO thread to
>> read if you want:
>> http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value
>>
>> It's unsafe in Java to sync on Byte, Short, Integer, Long, Float,
>> Double, Boolean, and Char.
>>
>> I assume in Groovy it is unsafe to sync on byte, short, integer, long,
>> float, double, boolean, and char primitive types. Is that correct?
>>
>> Now how does type promotion play with synchronization... Assuming you
>> sync on a final field, then it is OK to sync on a final BigInteger or
>> BigDecimal because these fields are final. Is that correct as well?
>>
>> Thanks,
>>
>> --
>> Hamlet D'Arcy
>> [hidden email]
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>    http://xircles.codehaus.org/manage_email
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|

Re: synchronization token in Groovy

Alex Tkachman
I would say if it is Serializable dont synchronize on it at all :)

On Tue, Feb 1, 2011 at 8:59 PM, Hamlet D'Arcy <[hidden email]> wrote:

> Thanks Alex, that was my understanding too.
>
> And if your class is Serializable... don't sync on new Object() but
> instead new Object[0].
>
>
> --
> Hamlet D'Arcy
> [hidden email]
>
>
> On Tue, Feb 1, 2011 at 7:44 PM, Alex Tkachman <[hidden email]> wrote:
>> The rules are simple:
>>
>> 1) there is no real way to sync on primitive in JVM Only on objects
>>
>> 2) This is absolutely OK to sync on instances of any type as long as
>> the instance is "unique" in the sense. So your code below is 100%
>> legal but it is wrong in a sense that
>> some other guy could decide to sync on another instance of Integer
>> representing number 5 but compiler or JRE or JVM will optimize it in a
>> way that you will share the same instance.  This is reason why you
>> never should synchronize on strings (even synchronization on interned
>> ones is not the best idea).
>>
>> class A {
>>   final Integer lock = 5;
>>   void method() {
>>    synchronized(lock) { ... }    // BAD!
>>  }
>> }
>>
>> 3) Best practice I think is always sync on specially allocated new
>> Object(), which created once in constructor, kept in private field and
>> never changed. Or to know for sure  (which is usually not possible)
>> what gonna happen if you synchronize on this. Normally it is good way
>> to deadlock :)
>>
>> My personal belief is "avoid synchronized if you can and see what you
>> are doing wrongly if you can not"
>>
>> On Tue, Feb 1, 2011 at 8:23 PM, Hamlet D'Arcy <[hidden email]> wrote:
>>> Hi All, I have a Groovy concurrency question and thought someone here
>>> might help.
>>>
>>> In Java, you should not synchronize on boxed primitives:
>>> class A {
>>>  final Integer lock = 5;
>>>  void method() {
>>>    synchronized(lock) { ... }    // BAD!
>>>  }
>>> }
>>>
>>> Since Integer objects can be cached and shared, this code could be
>>> synchronizing on the same object as other, unrelated code, leading to
>>> unresponsiveness and possible deadlock. There is a whole SO thread to
>>> read if you want:
>>> http://stackoverflow.com/questions/659915/synchronizing-on-an-integer-value
>>>
>>> It's unsafe in Java to sync on Byte, Short, Integer, Long, Float,
>>> Double, Boolean, and Char.
>>>
>>> I assume in Groovy it is unsafe to sync on byte, short, integer, long,
>>> float, double, boolean, and char primitive types. Is that correct?
>>>
>>> Now how does type promotion play with synchronization... Assuming you
>>> sync on a final field, then it is OK to sync on a final BigInteger or
>>> BigDecimal because these fields are final. Is that correct as well?
>>>
>>> Thanks,
>>>
>>> --
>>> Hamlet D'Arcy
>>> [hidden email]
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe from this list, please visit:
>>>
>>>    http://xircles.codehaus.org/manage_email
>>>
>>>
>>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe from this list, please visit:
>>
>>    http://xircles.codehaus.org/manage_email
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list, please visit:
>
>    http://xircles.codehaus.org/manage_email
>
>
>

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email