Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7973087
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 4, 20262026-06-04T08:00:59+00:00 2026-06-04T08:00:59+00:00

According to: http://www.ibm.com/developerworks/library/j-jtp03304/ Under the new memory model, when thread A writes to a

  • 0

According to:

http://www.ibm.com/developerworks/library/j-jtp03304/

Under the new memory model, when thread A writes to a volatile variable V, and thread B reads from V, any variable values that were visible to A at the time that V was written are guaranteed now to be visible to B

And many places on the internet state that the following code should never print “error”:

public class Test {
    volatile static private int a;
    static private int b;

    public static void main(String [] args) throws Exception {
        for (int i = 0; i < 100; i++) {
            new Thread() {

                @Override
                public void run() {
                    int tt = b; // makes the jvm cache the value of b

                    while (a==0) {

                    }

                    if (b == 0) {
                        System.out.println("error");
                    }
                }

            }.start();
        }

        b = 1;
        a = 1;
    }
}

b should be 1 for all the threads when a is 1.

However I sometimes get “error” printed. How is this possible?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-04T08:01:01+00:00Added an answer on June 4, 2026 at 8:01 am

    Update:

    For anyone interested this bug has been addressed and fixed for Java 7u6 build b14. You can see the bug report/fixes here

    • Report
    • Changeset
    • Buglist

    Original Answer

    When thinking in terms of memory visibility/order you would need to think about its happens-before relationship. The important pre condition for b != 0 is for a == 1. If a != 1 then b can be either 0 or 1.

    Once a thread sees a == 1 then that thread is guaranteed to see b == 1.

    Post Java 5, in the OP example, once the while(a == 0) breaks out b is guaranteed to be 1

    Edit:

    I ran the simulation many number of times and didn’t see your output.

    What OS, Java version & CPU are you testing under?

    I am on Windows 7, Java 1.6_24 (trying with _31)

    Edit 2:

    Kudos to the OP and Walter Laan – For me it only happened when I switched from 64 bit Java to 32 bit Java, on (but may not be excluded to) a 64 bit windows 7.

    Edit 3:

    The assignment to tt, or rather the staticget of b seems to have a significant impact (to prove this remove the int tt = b; and it should always work.

    It appears the load of b into tt will store the field locally which will then be used in the if coniditonal (the reference to that value not tt). So if b == 0 is true it probably means that the local store to tt was 0 (at this point its a race to assign 1 to local tt). This seems only to be true for 32 Bit Java 1.6 & 7 with client set.

    I compared the two output assembly and the immediate difference was here. (Keep in mind these are snippets).

    This printed "error"

     0x021dd753: test   %eax,0x180100      ;   {poll}
      0x021dd759: cmp    $0x0,%ecx
      0x021dd75c: je     0x021dd748         ;*ifeq
                                            ; - Test$1::run@7 (line 13)
      0x021dd75e: cmp    $0x0,%edx
      0x021dd761: jne    0x021dd788         ;*ifne
                                            ; - Test$1::run@13 (line 17)
      0x021dd767: nop    
      0x021dd768: jmp    0x021dd7b8         ;   {no_reloc}
      0x021dd76d: xchg   %ax,%ax
      0x021dd770: jmp    0x021dd7d2         ; implicit exception: dispatches to 0x021dd7c2
      0x021dd775: nop                       ;*getstatic out
                                            ; - Test$1::run@16 (line 18)
      0x021dd776: cmp    (%ecx),%eax        ; implicit exception: dispatches to 0x021dd7dc
      0x021dd778: mov    $0x39239500,%edx   ;*invokevirtual println
    

    And

    This did not print "error"

    0x0226d763: test   %eax,0x180100      ;   {poll}
      0x0226d769: cmp    $0x0,%edx
      0x0226d76c: je     0x0226d758         ;*ifeq
                                            ; - Test$1::run@7 (line 13)
      0x0226d76e: mov    $0x341b77f8,%edx   ;   {oop('Test')}
      0x0226d773: mov    0x154(%edx),%edx   ;*getstatic b
                                            ; - Test::access$0@0 (line 3)
                                            ; - Test$1::run@10 (line 17)
      0x0226d779: cmp    $0x0,%edx
      0x0226d77c: jne    0x0226d7a8         ;*ifne
                                            ; - Test$1::run@13 (line 17)
      0x0226d782: nopw   0x0(%eax,%eax,1)
      0x0226d788: jmp    0x0226d7ed         ;   {no_reloc}
      0x0226d78d: xchg   %ax,%ax
      0x0226d790: jmp    0x0226d807         ; implicit exception: dispatches to 0x0226d7f7
      0x0226d795: nop                       ;*getstatic out
                                            ; - Test$1::run@16 (line 18)
      0x0226d796: cmp    (%ecx),%eax        ; implicit exception: dispatches to 0x0226d811
      0x0226d798: mov    $0x39239500,%edx   ;*invokevirtual println
    

    In this example the first entry is from a run that printed "error" while the second was from one which didnt.

    It seems that the working run loaded and assigned b correctly before testing it equal to 0.

      0x0226d76e: mov    $0x341b77f8,%edx   ;   {oop('Test')}
      0x0226d773: mov    0x154(%edx),%edx   ;*getstatic b
                                            ; - Test::access$0@0 (line 3)
                                            ; - Test$1::run@10 (line 17)
      0x0226d779: cmp    $0x0,%edx
      0x0226d77c: jne    0x0226d7a8         ;*ifne
                                            ; - Test$1::run@13 (line 17)
    

    While the run that printed "error" loaded the cached version of %edx

      0x021dd75e: cmp    $0x0,%edx
      0x021dd761: jne    0x021dd788         ;*ifne
                                            ; - Test$1::run@13 (line 17)
    

    For those who have more experience with assembler please weigh in 🙂

    Edit 4

    Should be my last edit, as the concurrency dev’s get a hand on it, I did test with and without the
    int tt = b; assignment some more. I found that when I increase the max from 100 to 1000 there seems to be a 100% error rate when int tt = b is included and a 0% chance when it is excluded.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

According to http://www.cplusplus.com/reference/stl/deque/push_front/ x is Value to be copied to the new element. T
According to http://www.codeguru.com/forum/showthread.php?t=463663 , C#'s getHashCode function in 3.5 is implemented as: public override
http://www.frostjedi.com/terra/scripts/demo/jquery02.html According to this link elements can be moved around by doing $('#container1').append($('#container2')). Unfortunately,
According to, http://www.freshvanilla.org:8080/display/www/Java+Interview+Questions Under Which class is the superclass of every class? null seems
According to the Azure homepage, it says: [Storage, measured in GB] (http://www.windowsazure.com/en-us/pricing/details/) Storage is
According to http://www.rebol.com/docs/core23/rebolcore-15.html You can use change/part to parse and replace but that doesn't
According to http://www.assembla.com/wiki/show/scala-ide/Troubleshooting in order to have the Scala Eclipse plugin to work with
according to http://www.w3schools.com/dom/dom_node.asp , to get the text content of a node, textContent for
According to http://www.cplusplus.com/reference/clibrary/ctime/time_t/ time_t is the number of seconds since midnight 1/1/1970 UTC. So
I have this chunk of code which I found and implemented according to http://www.activexperts.com/activmonitor/windowsmanagement/scripts/networking/windowsfirewall/

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.