Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中监视异步请求_Java - Fatal编程技术网

如何在Java中监视异步请求

如何在Java中监视异步请求,java,Java,我有两门课。一个(A)收集一些数据,另一个(B)将数据发送到TCP/IP客户端。该过程是异步的,刷新率从接近零到几秒钟不等。 请注意,此应用程序没有GUI,因此我无法使用许多内置的“onChange”侦听器 在正常情况下,我只需编写代码,以便A调用B上的“send”方法,传递数据,这里没有问题 现在,假设A收集数据的速率非常关键(实时),并且A不能等待B完成发送过程(注意B使用TCP,而不是UDP)。我实现这一点的方式是 A将数据放在B中的字段中 B有一个连续循环,检查数据是新的还是现在的。如

我有两门课。一个(A)收集一些数据,另一个(B)将数据发送到TCP/IP客户端。该过程是异步的,刷新率从接近零到几秒钟不等。 请注意,此应用程序没有GUI,因此我无法使用许多内置的“onChange”侦听器

在正常情况下,我只需编写代码,以便A调用B上的“send”方法,传递数据,这里没有问题

现在,假设A收集数据的速率非常关键(实时),并且A不能等待B完成发送过程(注意B使用TCP,而不是UDP)。我实现这一点的方式是

  • A将数据放在B中的字段中
  • B有一个连续循环,检查数据是新的还是现在的。如果是新的,它会发送出去
如果在发送过程中,数据被更新了几次,只要数据不会减慢速度,就无所谓了。 原则上,为每次发送生成一个新线程不会降低发送速度,但可能会导致混乱

您可以看到B是在同步模式下工作的(但A不是),它是通过一个带有Thread.sleep()调用的while循环实现的。我的问题是:

  • 我应该使用计时器任务而不是while循环吗?我知道大多数人都讨厌Thread.sleep()调用,但最终我唯一感兴趣的是保持低CPU

  • 难道没有比同步方法更优雅的方法吗?在某些情况下,A的数据刷新时间约为1秒,如果我能有一个侦听器对事件进行处理,那就太好了。在这种情况下,25毫秒的睡眠时间将是对周期的浪费。在其他情况下,速度非常快,我不想睡觉


  • *示例:假设A正在从您的屏幕提交屏幕截图,而B正在将其发送给客户端。只有最后一个重要,B会尽可能快*

    有什么想法或建议吗?请让事情尽可能简单和低cpu


    非常感谢

    最优雅的方式是使用
    A
    在队列可用时立即将数据写入队列。B订阅队列,并在新数据出现时收到通知。消息队列为您处理一切

    但是,您应该更明确:是否应该为每条消息通知
    B
    ?如果更新丢失怎么办?

    我会在
    a
    B
    之间设置一个,当队列满时,其大小不应阻止
    a
    。在
    A
    中,收集数据的方法将其发布到队列。在
    B
    中,只要队列中有一个项目,它就是新的,应该发送出去

    如果您希望
    B
    利用
    a
    对消息的多个编辑来合并并作为单个更新发送出去,那么我将使用

  • A
    不断更新的消息是
    可观察的
  • B
    是此消息的观察者
  • 每次
    A
    更新消息时,都表示B需要采取一些措施
  • B
    可以选择立即向客户端发送更新
  • B
    还可以选择使用计时器等待一段时间,并仅在计时器触发后将更新发送给客户端。发送更新的代码将是TimerTask
  • B
    A
    更改消息之前不会再次设置计时器

  • 我会这样做:

    A以任何适当的方式收集数据,然后发布“下一条消息”以发送。如果已经有消息挂起,则让新消息替换/更新以前的消息

    B检查ay挂起的消息,如果有可用的消息,它将获取该消息并将其发送给客户端。但是,如果没有消息挂起,那么B将等待一条消息可用

    Object lock = new Object();
    Object pending = null;
    
    public void post(Object message) {
        synchronized (lock) {
            pending = message;
            lock.notifyAll();
        }
    }
    
    public Object getNextMessage() {
        Object message;
        synchronized (lock) {
            while (pending == null) {
                try {
                    lock.wait();
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
            message = pending;
            pending = null;
        }
        return message;
    }
    
    使用队列,您可以执行以下操作

    BlockingDeque<Object> queue = new LinkedBlockingDeque<Object>(1);
    
    public void postMessage(Object message) {
        // If previous message is still pending we replace it.
        queue.clear();
        queue.offer(message);
    }
    
    public Object getNextMessage() {
        while (true) {
            try {
                return queue.take();
            } catch (InterruptedException e) {
                // Ignore interrupts
            }
        }
    }
    
    BlockingDeque队列=新的LinkedBlockingDeque(1);
    公共void postMessage(对象消息){
    //如果上一条消息仍然挂起,我们将替换它。
    queue.clear();
    队列。提供(消息);
    }
    公共对象getNextMessage(){
    while(true){
    试一试{
    返回队列。take();
    }捕捉(中断异常e){
    //忽略中断
    }
    }
    }
    
    当然,在这两个例子中,最好不要使用while(true)信号,这样您就可以正常关机。

    您可以使用

    B将发送信息,使用交换机进行交换(他可能会等待A及其罚款)
    交换完成后,他将发送信息

    A将使用超时为0的交换机,这意味着如果B尚未等待,则我们将跳过此交换,如果他正在等待,则将进行交换,A将继续其工作,B现在可以发送信息


    B忙时出现的信息将被忽略(如果B忙,超时为0的A中的exchange只会引发异常,请确保您捕获它)

    实际上,我只需要B发送可用的最新数据,不需要通知(抱歉,我应该在帖子中写入),因此不确定队列是否正确。例如,后进先出队列会首先传输最新的信息,但最终我会将旧数据发送到客户端。。其他想法?所以,它不是绝对意义上的最新数据,只有在
    B
    获取它之前才是最新的,对吗?只需要确认我是否理解正确。是的,假设A正在从您的屏幕提交屏幕截图,B正在将其发送给客户。只有最后一个重要,B会尽可能快possible@EmanueleRonchi,我使用
    Observer
    模式更新了消息。实际上,我只需要B发送可用的最新数据,不需要通知(对不起,我应该在帖子中写下),所以不确定队列是否正确。例如,后进先出队列会首先传输最新的信息,但最终我还是会失败