1

I am working on a simple component where my class holds a reference to an object that support add operations and a submit function.
Once the submit function is called, the referenced object needs to be replaced with a new one. My API supports add operations that submits the item once it reached a certin size BUT in some cases i will need to verify that an item has been submitted regardless of its size after some time. The only solution i could think of is synchronizing the entire class, which i would like to avoid. Any thoughts of other solutions/possible refactoring to avoid synchronizing everything?

pulic class MyClass{
        private MyObject ref;
        private int maxObjectsToSubmit;

        public MyClass(int maxItems){ 
              this.maxObjectsToSubmit = maxItems;
        }

        public void add(Item obj){
              ref.add(obj);
              if(ref.size() == maxObjectsToSubmit){
                   submit();
              }else if(obj.isVeryImportant()){
                    SomeAPI.runThreadInExactDelayToCreateRaceCondition(new Runnable{ 
                     public void run(){
                          //Submit only if o is still waiting to be submittet.
                     // if ref does not contains obj than it has already been submitted
                         if(ref.contains(obj)){
                           submit()
                         }
                  })
             }
        }

           private void submit(){
                 SomeAPI.doSomething(ref);
                 this.ref = new MyObject();
            }
}

Race condition is:

  1. T1 adds some items untill a veryImpotant item arrives, which starts T2
  2. T1 reaches maxObjectsToSubmit and ref.size() == maxObjectsToSubmit returns true
  3. T2 starts, ref.contains(obj) returns true

This can result in an empty object being submitted / Same object being submitted twice/etc'

2
  • 1
    Make your MyObject immutable. Commented Jan 15, 2019 at 11:04
  • It is very important to find the right names for things in OO-programming. In the example you gave us, the names are MyObject and MyClass, but these are bad names. What I like is, that you have already more than one class, so you can follow the 'Single responsibility principle'. Commented Jan 15, 2019 at 11:20

1 Answer 1

2

My suggestion would be to create a new Myobject instance and insert the obj item in it and then call submit since it is high priority , it should not wait for the Myobject to reach max limit.

public void add(Item obj) {
        if (obj.isVeryImportant()) {
            SomeAPI.runThreadInExactDelayToCreateRaceCondition(new Runnable {
                public void run () {
                    //Submit only if o is still waiting to be submittet.
                    // if ref does not contains obj than it has already been submitted
                    MyObject local = new MyObject();
                    local.add(obj);
                    local.submit();
                }
            });
        } else {
            ref.add(obj);
            if (ref.size() == maxObjectsToSubmit) {
                submit();
            } else if (obj.isVeryImportant()) {

            }
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.