TheDude
TheDude

Reputation: 391

Avoiding synchronized blocks in java code

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'

Upvotes: 1

Views: 70

Answers (1)

Mr Nobody
Mr Nobody

Reputation: 396

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()) {

            }
        }
    }

Upvotes: 2

Related Questions