避免Java代码中的同步块

时间:2019-01-15 10:35:15

标签: java multithreading synchronization thread-safety

我正在研究一个简单的组件,该类中的类包含对支持添加操作和提交功能的对象的引用。
调用Submit函数后,需要用一个新对象替换引用的对象。 我的API支持添加操作,该操作会在商品达到certin大小时提交该商品,但在某些情况下,我将需要验证商品已提交,而不管其大小如何。 我唯一想到的解决方案是同步整个类,这是我想避免的。为了避免同步所有其他解决方案/可能的重构的想法?

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();
            }
}

种族条件是:

  1. T1添加一些项目,直到一个非常重要的项目到来,这开始了T2
  2. T1到达maxObjectsToSubmit并且ref.size()== maxObjectsToSubmit返回true
  3. T2启动,ref.contains(obj)返回true

这可能会导致提交一个空对象/同一对象被提交两次/等'

1 个答案:

答案 0 :(得分:2)

我的建议是创建一个新的Myobject实例,然后在其中插入obj项,然后调用Submit,因为它具有较高的优先级,因此不应等待Myobject达到最大限制。

"domain.com/places/place-hong-kong/"
"domain.com/places/place-usa/"
"domain.com/places/place-israel/"
"domain.com/places/place-denemark/"