Topic
  • 2 replies
  • Latest Post - ‏2007-11-07T15:20:09Z by SystemAdmin
SystemAdmin
SystemAdmin
1240 Posts

Pinned topic Threading Lightly Part 1. Where is the race condition

‏2007-08-17T21:50:10Z |
code
...
private int foo;
public synchronized int getFoo() { return foo; }
public synchronized void setFoo(int f) { foo = f; }
[/code]
If a caller wants to increment the foo property, the following code to do so is not thread-safe:

...
setFoo(getFoo() + 1);
If two threads attempt to increment foo at the same time, the result might be that the value of foo gets increased by one or by two, depending on timing.
Updated on 2007-11-07T15:20:09Z at 2007-11-07T15:20:09Z by SystemAdmin
  • SystemAdmin
    SystemAdmin
    1240 Posts

    Re: Threading Lightly Part 1. Where is the race condition

    ‏2007-08-17T22:11:08Z  
    I Accidentally submitted the previous post before completing it, here's the correct post:

    In Threading Lightly Part 1 we are shown this example code:
    code
    ...
    private int foo;
    public synchronized int getFoo() { return foo; }
    public synchronized void setFoo(int f) { foo = f; }
    [/code]

    Then the author states:
    [b]If a caller wants to increment the foo property, the following code to do so is not thread-safe:[/b]
    code
    ...
    setFoo(getFoo() + 1);
    [/code]

    The given reason why this isn't thread-safe is:
    [b]If two threads attempt to increment foo at the same time, the result might be that the value of foo gets increased by one or by two, depending on timing. [/b]

    As someone quite new to java threading, the race condition here isn't obvious to me. I understand (perhaps wrongly) that the consequences of synchronizing those two methods are this:
    One thread at a time may be executing in those two methods, such that while a thread is running in setFoo(), no thread may enter setFoo() or getFoo(), until the currently running thread completes the method run.

    You can perhaps see how someone this this understanding of synchronization cannot see the race condition on the aforementioned example. Here's my reasoning:
    -Suppose that two threads want to enter the setFoo() method as in the example.
    -Only one of those threads will enter the method because it's sychronized.
    -The second thread cannot possibly enter until the first thread exits the synchronized method.
    Thus how is it possible that the property may either be incremented by 1 or 2 ?

    Some guidance would be appreciated. In the mean time I think i'll read up on synchronization and see if that clears things up.

    Thanks for reading
    -DSko
  • SystemAdmin
    SystemAdmin
    1240 Posts

    Re: Threading Lightly Part 1. Where is the race condition

    ‏2007-11-07T15:20:09Z  
    I Accidentally submitted the previous post before completing it, here's the correct post:

    In Threading Lightly Part 1 we are shown this example code:
    code
    ...
    private int foo;
    public synchronized int getFoo() { return foo; }
    public synchronized void setFoo(int f) { foo = f; }
    [/code]

    Then the author states:
    [b]If a caller wants to increment the foo property, the following code to do so is not thread-safe:[/b]
    code
    ...
    setFoo(getFoo() + 1);
    [/code]

    The given reason why this isn't thread-safe is:
    [b]If two threads attempt to increment foo at the same time, the result might be that the value of foo gets increased by one or by two, depending on timing. [/b]

    As someone quite new to java threading, the race condition here isn't obvious to me. I understand (perhaps wrongly) that the consequences of synchronizing those two methods are this:
    One thread at a time may be executing in those two methods, such that while a thread is running in setFoo(), no thread may enter setFoo() or getFoo(), until the currently running thread completes the method run.

    You can perhaps see how someone this this understanding of synchronization cannot see the race condition on the aforementioned example. Here's my reasoning:
    -Suppose that two threads want to enter the setFoo() method as in the example.
    -Only one of those threads will enter the method because it's sychronized.
    -The second thread cannot possibly enter until the first thread exits the synchronized method.
    Thus how is it possible that the property may either be incremented by 1 or 2 ?

    Some guidance would be appreciated. In the mean time I think i'll read up on synchronization and see if that clears things up.

    Thanks for reading
    -DSko
    setFoo(getFoo() + 1);
    For example getFoo()=1

    Case 1:
    Step 1. Thread1 somevar4Thread1 = getFoo() //1
    Step 2. Thread2 somevar4Thread2 = getFoo() //1
    Step 3. Thread1 tmpVarThread1=somevar4Thread1+1 //2
    Step 4. Thread2 tmpVarThread2=somevar4Thread2+1 //2
    Step 5. Thread1 setFoo(tmpVarThread1) //2
    Step 6. Thread2 setFoo(tmpVarThread2) //2
    Case 2:
    Step 1. Thread1 somevar4Thread1 = getFoo() //1
    Step 2. Thread1 tmpVarThread1=somevar4Thread1+1 //2
    Step 3. Thread1 setFoo(tmpVarThread1) //2
    Step 4. Thread2 somevar4Thread2 = getFoo() //2
    Step 5. Thread2 tmpVarThread2=somevar4Thread2+1 //3
    Step 6. Thread2 setFoo(tmpVarThread2) //3