【问题标题】:How to use callbacks right?如何正确使用回调?
【发布时间】:2013-05-30 11:15:57
【问题描述】:

我弄乱了一些模式,以使代码更加模块化。所以我有这样的事情:

class A implements ICallback {
     MyObject o;
     B b = new B(this, someParameter);

     @Override
     public void callback(MyObject o){
           this.o = o;
     }
}

class B {
     ICallback ic;
     B(ICallback ic, someParameter){
         this.ic = ic;
     }

    new Thread(new Runnable(){
         public void run(){
             // some calculation
             ic.callback(myObject)
         }
    }).start(); 
}

interface ICallback(){
    public void callback(MyObject o);
}

我必须在A 中等待MyObject,所以如果B 中的Thread 的工作完成,我将使用callback 通知A。但现在我必须将所有逻辑都放在处理MyObject 并在callback 中进行进一步处理。

我能以某种方式避免这种情况吗,或者那是正确的方法吗?

【问题讨论】:

  • 为什么要避免这种情况?有什么原因吗?
  • 不清楚你想做什么和避免什么。原则上,您的代码是可以接受的,但请记住,A.callback() 是从 B 中的线程调用的,因此如果您想从其他线程访问 A 的字段,例如创建A实例的线程,那么你需要添加一些同步。
  • 我要求避免这种情况,因为我的整个程序都依赖于 MyObject。所以所有的工作都必须在那个回调中完成。

标签: java multithreading callback


【解决方案1】:

您的方法基本上是合理的,但class A 本身可能不应该实现ICallback。更典型、更灵活的方案是将匿名回调实现的实例传递给B

还要注意,回调的所有处理都将在B启动的线程上完成。

与上述观察相关的是您对callback 进行MyObject 的所有处理的疑虑的答案:基本上没有其他方法可以做到,因为提供MyObject 的动作是由B 发起的的线程和控件只能从该方法向外流动。如果您希望处理跳转到主线程,则需要一个涉及阻塞队列的更复杂的方案。

【讨论】:

  • 是的,你的意思是 IoC。但我的想法是检查线程是否完成或更具体,如果 MyObject 在类 A 中实例化并准备好在回调之外使用。我之所以这么问,是因为我唯一想到的就是投票。
  • 轮询不会是一个绝妙的选择,也不会在预期事件时阻塞线程。实际上,最好的方法是从回调中完成所有逻辑,特别是最现代的异步 Java I/O API 就是这样工作的。
猜你喜欢
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 1970-01-01
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-19
相关资源
最近更新 更多