以单线程方式包装回调函数

时间:2012-07-03 18:04:10

标签: java multithreading

在我的程序中,我基本上是尝试连接到发布者并获取数据。这些步骤中有基本功能

  1. 我使用用户名和密码等与发布商建立了连接
  2. 我提出了数据请求。方法退出
  3. 发布商的API为我提供了对方法onDataUpdate(Object theUpdate)
  4. 的回调

    从那里,我可以打印数据,或将数据写入数据库或我需要做的任何事情。这一切都有效。

    我的问题是,我现在想要以这样一种方式包装功能,即调用程序可以说请求数据并在我拥有数据后立即接收它。意思是,我希望我的暴露方法看起来像

    public Object getData() {
        subscribeForData();
        // somehow wait
        return theUpdate;    
    }
    

    我怎样才能实现这一目标?有没有什么方法可以在我收到更新时使用线程等待/通知?我是stackoverflow和多线程编程的新手,所以任何帮助和示例代码将非常感谢!!提前谢谢。

5 个答案:

答案 0 :(得分:1)

在这种情况下,我更倾向于使用CountDownLatch,我将在lathch初始化我的await(,我将尽快订阅发布商,我会在{{1}上调用latch}当我得到回调时,我会countdown latch

答案 1 :(得分:0)

使用SynchronousQueue。在getData中创建它,在回调方法中调用put(),然后在getData()的末尾调用原始线程中的take()。

答案 2 :(得分:0)

查看CompletionService,尤其是ExecutorCompletionService。在 Java Concurrency in Practice 一书中有一个很好的网页加载器/渲染器示例。

答案 3 :(得分:0)

我不完全确定你的问题,但我会试一试 - 希望它有所帮助:)

你可以在java中为此目的使用阻塞队列(生产者消费者消息) - 如果你在调用回调时写入队列 - 从另一个线程,你可以从队列中读取。阻塞队列是线程安全的(但可能不符合您的要求)。

如果你只有一个线程写入一个集合,也许还有多个读者(或者甚至只是读者),你也可以查看readwrite锁。

您还可以查看观察者模式 - 供参考:http://www.vogella.com/articles/DesignPatternObserver/article.html

如果这些都不起作用,可以考虑使用来自VM内部消息服务器的队列/主题,例如ZeroMQ / ActiveMQ或类似Redis / HazelCast。

希望它有所帮助,祝你好运

答案 4 :(得分:0)

将异步调用转换为同步调用是一项有趣的练习,我经常在访谈中使用它(相反,在异步中包装同步调用)。

所以有一个requestData方法会立即返回,而它(或其他东西)稍后会在一个不同的线程中调用onDataUpdate 。您想要创建一个新方法,比如requestDataSynchronous,不要求调用者使用回调,而是阻止,直到数据可用并将其返回给调用者。

所以requestDataSynchronous需要做的是:

  1. 致电requestData
  2. 等到onDataUpdate被调用(在另一个帖子中)
  3. 获取收到的数据onDataUpdate
  4. 将其返回给来电者
  5. 在上述中,#2和#3必须通过某种线程间通信模式完成。您可以使用wait / notifiy,但使用BlockingQueue可能会更简单。数据可用后,onDataUpdate会向其发送信息,并requestDataSynchronous从中读取,阻止读取,直到onDataUpdate写入数据。

    使用ExecutorService可能会让这更容易,但知道发生了什么会很有用。