Threads 101 question

Discussion in 'Java' started by Mike Smith, May 12, 2004.

  1. Mike Smith

    Mike Smith Guest

    How do you handle this paradox?

    1. Object myObject = new Object();
    2.
    3. // Threads started here which
    4. // may set myObject to null
    5.
    6. if (myObject != null) {
    7. synchronized (myObject) {
    8. // Ref to myObject here
    9. }
    10. }

    How can you be sure another thread will not swoop in and set myObject
    to null in between lines 6 and 7 before you have a chance to get a
    lock on it? You cannot synchronize on myObject if it is set to null
    without throwing an exception. Do you just move the synchronized
    block to before the IF statement and catch the exception if myObject
    is null or is there a more elegant approach?

    Mike
     
    Mike Smith, May 12, 2004
    #1
    1. Advertising

  2. Mike Smith

    Eric Sosman Guest

    Mike Smith wrote:
    > How do you handle this paradox?
    >
    > 1. Object myObject = new Object();
    > 2.
    > 3. // Threads started here which
    > 4. // may set myObject to null
    > 5.
    > 6. if (myObject != null) {
    > 7. synchronized (myObject) {
    > 8. // Ref to myObject here
    > 9. }
    > 10. }
    >
    > How can you be sure another thread will not swoop in and set myObject
    > to null in between lines 6 and 7 before you have a chance to get a
    > lock on it? You cannot synchronize on myObject if it is set to null
    > without throwing an exception. Do you just move the synchronized
    > block to before the IF statement and catch the exception if myObject
    > is null or is there a more elegant approach?


    Another thread can indeed swoop in and do the dirty deed.
    However, `myObject' cannot be a method-local variable or method
    parameter (such things are private to each thread), so the deed
    can only be done if `myObject' is a member variable in some
    other object (or class). And in that case, the thing you want to
    lock is not the object pointed to by `myObject', but the object
    containing the `myObject' member.

    Or to look at it a slightly different way: The thing that
    the threads are sharing is not really the newly-created Object,
    but the object that contains `myObject'. Since they share that
    enclosing object, they must synchronize their accesses to it.

    --
     
    Eric Sosman, May 12, 2004
    #2
    1. Advertising

  3. Mike Smith

    Liz Guest

    "Mike Smith" <> wrote in message
    news:...
    > How do you handle this paradox?
    >
    > 1. Object myObject = new Object();
    > 2.
    > 3. // Threads started here which
    > 4. // may set myObject to null
    > 5.
    > 6. if (myObject != null) {
    > 7. synchronized (myObject) {
    > 8. // Ref to myObject here
    > 9. }
    > 10. }
    >
    > How can you be sure another thread will not swoop in and set myObject
    > to null in between lines 6 and 7 before you have a chance to get a
    > lock on it? You cannot synchronize on myObject if it is set to null
    > without throwing an exception. Do you just move the synchronized
    > block to before the IF statement and catch the exception if myObject
    > is null or is there a more elegant approach?
    >
    > Mike


    How about if you just an another 'if' between lines 7 and 8
     
    Liz, May 12, 2004
    #3
  4. Mike Smith

    Mike Smith Guest

    myObject would never be null since the synchronized operation would
    have thrown an exception if it was null and would have locked it for
    me if it was not null, so an IF there makes no difference. It will
    never get there without myObject being a non-null reference -
    guaranteed. Someone please correct me if I'm wrong.

    I think the earlier post from Eric Sosman nails it but I'm still
    digesting that information.

    Mike

    "Liz" <> wrote in message
    news:Yktoc.34950$iF6.3474186@attbi_s02...
    >
    > "Mike Smith" <> wrote in message
    > news:...
    > > How do you handle this paradox?
    > >
    > > 1. Object myObject = new Object();
    > > 2.
    > > 3. // Threads started here which
    > > 4. // may set myObject to null
    > > 5.
    > > 6. if (myObject != null) {
    > > 7. synchronized (myObject) {
    > > 8. // Ref to myObject here
    > > 9. }
    > > 10. }
    > >
    > > How can you be sure another thread will not swoop in and set myObject
    > > to null in between lines 6 and 7 before you have a chance to get a
    > > lock on it? You cannot synchronize on myObject if it is set to null
    > > without throwing an exception. Do you just move the synchronized
    > > block to before the IF statement and catch the exception if myObject
    > > is null or is there a more elegant approach?
    > >
    > > Mike

    >
    > How about if you just an another 'if' between lines 7 and 8
    >
    >
     
    Mike Smith, May 12, 2004
    #4
  5. Mike Smith

    Mike Smith Guest

    Interesting... So to lock a critical block within a method I would use
    synchronize(this) as follows:

    1. myObject = new Object(); // myObject is now a class var
    2.
    3. // Threads started here which
    4. // may set myObject to null
    5. if (xxx) {
    6. // non critical code goes here
    7. } else {
    8. synchronize(this) {
    9. if (myObject != null) {
    10. // critcal code goes here
    11. }
    12. }
    13.}

    Thanks for your help, assuming I got it right. (synchronize this, wasn't
    that a Billy Crystal movie?)

    Mike


    "Eric Sosman" <> wrote in message
    news:...
    > Mike Smith wrote:
    > > How do you handle this paradox?
    > >
    > > 1. Object myObject = new Object();
    > > 2.
    > > 3. // Threads started here which
    > > 4. // may set myObject to null
    > > 5.
    > > 6. if (myObject != null) {
    > > 7. synchronized (myObject) {
    > > 8. // Ref to myObject here
    > > 9. }
    > > 10. }
    > >
    > > How can you be sure another thread will not swoop in and set myObject
    > > to null in between lines 6 and 7 before you have a chance to get a
    > > lock on it? You cannot synchronize on myObject if it is set to null
    > > without throwing an exception. Do you just move the synchronized
    > > block to before the IF statement and catch the exception if myObject
    > > is null or is there a more elegant approach?

    >
    > Another thread can indeed swoop in and do the dirty deed.
    > However, `myObject' cannot be a method-local variable or method
    > parameter (such things are private to each thread), so the deed
    > can only be done if `myObject' is a member variable in some
    > other object (or class). And in that case, the thing you want to
    > lock is not the object pointed to by `myObject', but the object
    > containing the `myObject' member.
    >
    > Or to look at it a slightly different way: The thing that
    > the threads are sharing is not really the newly-created Object,
    > but the object that contains `myObject'. Since they share that
    > enclosing object, they must synchronize their accesses to it.
    >
    > --
    >
    >
     
    Mike Smith, May 12, 2004
    #5
  6. Mike Smith wrote:
    > How do you handle this paradox?
    >
    > 1. Object myObject = new Object();
    > 2.
    > 3. // Threads started here which
    > 4. // may set myObject to null
    > 5.
    > 6. if (myObject != null) {
    > 7. synchronized (myObject) {
    > 8. // Ref to myObject here
    > 9. }
    > 10. }
    >
    > How can you be sure another thread will not swoop in and set myObject
    > to null in between lines 6 and 7 before you have a chance to get a
    > lock on it? You cannot synchronize on myObject if it is set to null
    > without throwing an exception. Do you just move the synchronized
    > block to before the IF statement and catch the exception if myObject
    > is null or is there a more elegant approach?
    >
    > Mike


    In the code you posted, another thread cannot accedd myObject because it
    is a thread-local variable, not a class or instance variable.

    Assuming that myObject was (say) an instance variable of an object, then
    I suggest you should only take one bite at the cherry, like this:

    // get the (possibly null) reference to the lock object
    Object myObject = holderObject.getLockObject();

    // now no-one can take it from us because we have a
    // thread-local reference to it.
    if(myObject != null) {
    // do something...


    Maybe you should be synchronizing on the next-level-up object
    that holds the lock object instead - sync on the parent not the child?

    Steve
     
    Steve Horsley, May 12, 2004
    #6
  7. Mike Smith

    Eric Sosman Guest

    Mike Smith wrote:
    > Interesting... So to lock a critical block within a method I would use
    > synchronize(this) as follows:
    >
    > 1. = new Object(); // myObject is now a class var
    > 2.
    > 3. // Threads started here which
    > 4. // may set myObject to null
    > 5. if (xxx) {
    > 6. // non critical code goes here
    > 7. } else {
    > 8. synchronize(this) {
    > 9. if (myObject != null) {
    > 10. // critcal code goes here
    > 11. }
    > 12. }
    > 13.}
    >
    > Thanks for your help, assuming I got it right. (synchronize this, wasn't
    > that a Billy Crystal movie?)


    Even though `synchronize' marks a region of code where
    a lock is to be held, I think it's easier to forget about
    the code and concentrate on the data. That is, instead of
    thinking about which pieces of code execute with a lock, think
    about which data objects require protection against simultaneous
    access.

    In your case, `myObject' is a member of some other object,
    the `this' above. `myObject' happens to be a reference variable,
    but it could just as well be a `double' or an `int': whatever
    it is, it's part of the "value" of the `this' object. If two
    or more threads are going to race each other to muck with the
    value of `this', their accesses to `this' must be protected.
    (There are some exceptions: Certain operations on some primitive
    types are guaranteed to be "atomic," and read-only accesses need
    not be protected against each other. Except for such special
    cases, though, the rule holds: Each shared object can only be
    modified or inspected while its lock is held.)

    Your revised code is now safe *provided* the other threads
    also synchronize on `this' (that is, on a reference to the same
    "ur-object;" it won't be called `this' in those threads) when
    they're mucking about with the `myObject' member. Your line 8
    will not provide protection all by itself; the rest of the code
    must follow the same discipline.

    So: Not only must Billy Crystal `synchronize(this)', but
    Robert De Niro must also `synchronize(that)'.

    --
     
    Eric Sosman, May 12, 2004
    #7
  8. Mike Smith

    Mike Smith Guest

    I got it! I will thead-way safely now.

    I think it was a movie about Java called "Synchronize This" where
    Billy Crystal played Scott McNeeley and Robert De Niro played Bill
    Gates and - oh wait, that wasn't a movie, it really happened! ;-)

    Mike


    ----- Original Message -----
    From: "Eric Sosman" <>
    Newsgroups: comp.lang.java.programmer
    Sent: Wednesday, May 12, 2004 1:31 PM
    Subject: Re: Threads 101 question


    > Mike Smith wrote:
    > > Interesting... So to lock a critical block within a method I

    would use
    > > synchronize(this) as follows:
    > >
    > > 1. = new Object(); // myObject is now a class var
    > > 2.
    > > 3. // Threads started here which
    > > 4. // may set myObject to null
    > > 5. if (xxx) {
    > > 6. // non critical code goes here
    > > 7. } else {
    > > 8. synchronize(this) {
    > > 9. if (myObject != null) {
    > > 10. // critcal code goes here
    > > 11. }
    > > 12. }
    > > 13.}
    > >
    > > Thanks for your help, assuming I got it right. (synchronize this,

    wasn't
    > > that a Billy Crystal movie?)

    >
    > Even though `synchronize' marks a region of code where
    > a lock is to be held, I think it's easier to forget about
    > the code and concentrate on the data. That is, instead of
    > thinking about which pieces of code execute with a lock, think
    > about which data objects require protection against simultaneous
    > access.
    >
    > In your case, `myObject' is a member of some other object,
    > the `this' above. `myObject' happens to be a reference variable,
    > but it could just as well be a `double' or an `int': whatever
    > it is, it's part of the "value" of the `this' object. If two
    > or more threads are going to race each other to muck with the
    > value of `this', their accesses to `this' must be protected.
    > (There are some exceptions: Certain operations on some primitive
    > types are guaranteed to be "atomic," and read-only accesses need
    > not be protected against each other. Except for such special
    > cases, though, the rule holds: Each shared object can only be
    > modified or inspected while its lock is held.)
    >
    > Your revised code is now safe *provided* the other threads
    > also synchronize on `this' (that is, on a reference to the same
    > "ur-object;" it won't be called `this' in those threads) when
    > they're mucking about with the `myObject' member. Your line 8
    > will not provide protection all by itself; the rest of the code
    > must follow the same discipline.
    >
    > So: Not only must Billy Crystal `synchronize(this)', but
    > Robert De Niro must also `synchronize(that)'.
    >
    > --
    >
    >
     
    Mike Smith, May 12, 2004
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TheCoder
    Replies:
    1
    Views:
    382
    =?Utf-8?B?UGV0ZXIgQnJvbWJlcmcgW0MjIE1WUF0=?=
    Dec 2, 2005
  2. =?Utf-8?B?am9uZWZlcg==?=

    101 Question - Passing a value from one page to another

    =?Utf-8?B?am9uZWZlcg==?=, Dec 22, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    441
    uttara
    Dec 22, 2005
  3. Roger Varley
    Replies:
    20
    Views:
    916
    jan V
    Aug 14, 2005
  4. ppcguy

    css 101 question

    ppcguy, Aug 20, 2005, in forum: HTML
    Replies:
    3
    Views:
    343
    Neredbojias
    Aug 20, 2005
  5. Ben

    Ruby Threads 101

    Ben, Sep 26, 2005, in forum: Ruby
    Replies:
    11
    Views:
    185
    Robert Klemme
    Sep 27, 2005
Loading...

Share This Page