1
        CustomObject foundCustomObject = null;

        while(true){
            System.out.println(System.identityHashCode(staticClass.getArrayList()));
            System.out.println(staticClass.getArrayList().size());
            for(CustomObject customObject : staticClass.getArrayList()){
                if(customObject.getCustomField().equals("")){
                    System.out.println("ADDED OBJECT FOUND!");
                    break;
                }
            }

            if(foundCustomObject != null){
                break;
            }else{
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

I have two threads, one is running the above code. The second thread is doing the following when the user clicks a button in my application:

        System.out.println("ADDING CUSTOM OBJECT TO LIST: "+System.identityHashCode(staticClass.getArrayList()));
        boolean success = staticClass.getArrayList().add(new CustomObject(System.currentTimeMillis()));
        System.out.println(success);

Every time the adding thread calls .add(), it returns true for success. However, sometimes the looping thread does not see the results of the .add() being called in the adding thread. By this, I mean that the size of the list does not increase and the object does not seem to actually be added as far as the looping thread knows. I am printing the memory addresses of the ArrayList in both threads to verify that they are the same. I don't understand how I can be calling .add() in one thread, checking the .size() in the other thread and not having it go up. If anyone has any idea why this behavior is occurring, please let me know.

EXAMPLE CONSOLE OUTPUT WHEN FAILING:

354613969  
0  
354613969  
0  
ADDING CUSTOM OBJECT TO LIST: 354613969  
true  
354613969  
0  
354613969  
0  
Mars
  • 2,505
  • 17
  • 26
  • 1
    Read this: https://www.infoq.com/articles/memory_barriers_jvm_concurrency – Nathan Hughes Sep 25 '18 at 01:26
  • You're not showing us enough info here. Is the list volatile? Also, you're not printing the memory address, you're printing the hashcode, which, for arraylists, changes every time you add or remove an object. – Mars Sep 25 '18 at 01:27
  • 2
    Normally you would be right about the hashcode, but I am using the java system default hashcode, not the overridden hashcode in arraylist. This is the objectid in memory regardless of class. – Brian Bokoske Sep 25 '18 at 01:30
  • How can you have no clue to this problem while know about the Java system identity hashcode? Seriously. – xiaofeng.li Sep 25 '18 at 01:34
  • Not that these two are related. The probability of this kind of combination is low, IMHO. – xiaofeng.li Sep 25 '18 at 01:35
  • The example was just coded to make an example of the behavior, the actual implementation is much different and is in code that I cannot share with the public. Because of that I just came up with a dumbed-down example that still displays the issue I am having. – Brian Bokoske Sep 25 '18 at 01:37
  • 3
    What synchronization primitives do you think you're using here to coordinate access to a shared resource between threads? I don't see any. – John H Sep 25 '18 at 01:38
  • Didn't realize that about System.identityHashCode! Getting nitpicky, but system.identityhashcode isn't necessarily the memory address either, its whatever the JVM implements it as. – Mars Sep 25 '18 at 01:41

0 Answers0