简体   繁体   English

Java-仅执行一次方法

[英]Java - execute method only once

I have a simple problem: 我有一个简单的问题:

Class A{

    B b;

    public void doSth{ 
         //This method should execute only once
         b.modify(); //calls doSth() again...
    }
}

As the program runs, an instance of A is passed to B, and B calls doSth (as a callback for instance). 程序运行时,将A的实例传递给B,然后B调用doSth(作为实例的回调)。 b.modify makes B to call A.doSth() again, which will infinite sequence of calls. b.modify使B再次调用A.doSth() ,这将无限次地进行调用。 What I want to achieve is this: I want to execute doSth() once, modify B, then upon next execution somehow stop the chain of inifinite calls and do not execute b.modify . 我要实现的目标是:我要执行一次doSth(),修改B,然后在下一次执行时以某种方式停止无限调用链,而不执行b.modify

Any suggestions greatly appreciated. 任何建议,不胜感激。

Add a state flag to your class: 将状态标志添加到您的班级:

Class A {

    B b;
    private volatile boolean called;

    public synchronized void doSth { 
         if (called) return;
         called = true;
         b.modify();
    }
}

Use volatile if multiple threads are in play. 如果有多个线程在使用,请使用volatile

You can have a boolean field and set it true the first time you call the method. 您可以拥有一个布尔字段,并在第一次调用该方法时将其设置为true。

Class A{
    boolean isModified = false;
    B b;

    public void doSth{ 
        if(!isModified) {
            this.isModified = true;
            b.modify();
        }
    }
}

I'd try to find a solution that doesn't involve circular dependencies. 我试图找到一种不涉及循环依赖的解决方案。 Do A and B really have to reference eachother? A和B真的必须互相引用吗? On a higher level, what are you trying to achieve? 在更高的层次上,您要达到什么目标? Could you post some client code using A and B objects? 您可以使用A和B对象发布一些客户端代码吗?

Add a boolean alreadyExecuted to class A and modify the implementation of doSmth() to 向类A添加一个boolean alreadyExecuted并将doSmth()的实现修改为

 public void doSth{ 
     if(!alreadyExecuted){
         alreadyExecuted = true; 
         b.modify(); 

     }
}

Consider this as a Hack... 将此视为骇客...

Use boolean variable 使用boolean变量

Class A{

    B b;
    public isOk = true;

    public void doSth{ 

        if (isOk){

         b.modify(); 
         isOk = false;

        }

}

maybe you should change design to not call those method recursively, or if you cant just add parameter to your doSth method 也许您应该更改设计以不递归地调用这些方法,或者如果您不能仅将参数添加到doSth方法中

doSth(boolean modify)
 {
  if (modify) 
  {
    b.modify();
  }
  ...
 }

This is a fix for "best" example, coz noone should really use it in concurrent/multithreading cases. 这是对“最佳”示例的修复,因为没有人真正应该在并发/多线程情况下使用它。 You can get both threads run "if" and both will pass to the next line. 您可以使两个线程都运行“ if”,并且两个线程都将传递到下一行。 It's better to use CAS here, something like: 最好在这里使用CAS,例如:

private final AtomicBoolean called = new AtomicBoolean();

and then

if (!called.compareAndSet(false, true)) return;

or if you prefer to use "plain and pure" style, use double checking with synchronized: 或者,如果您更喜欢使用“纯正的”样式,请对同步使用双重检查:

private volatile boolean called;

and then

boolean mayPass = false;
if (!called) {
  synchronized(this) { // or some external object
    if (!called) {
      called = true;
      mayPass = true;
    }
  }
}
if (!mayPass) return;
...

Put your job in the constructor 把你的工作放在构造函数中

Class A{

   B b;

   A(){
       //This should execute only once
       b.modify(); //calls doSth() again...
   }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM