【问题标题】:Run Java Code after a Method Return?在方法返回后运行 Java 代码?
【发布时间】:2012-02-14 11:31:54
【问题描述】:

我有一个基于 Java 类的 Web 服务。在被调用操作的 Java 方法中返回确认消息后是否可以运行代码。

为了更好地理解,这是工作流程:

  1. 调用我的 Web 服务的特定操作(方法)
  2. 开始处理
  3. 发送一个确认处理已经开始(这是一个返回值)
  4. 继续处理

线程不起作用,因为线程需要在方法返回之前终止。

有人知道如何实现这个场景或替代它吗?

提前致谢。

【问题讨论】:

  • 你想从一个方法返回而不是从该方法返回?这将是有问题的。
  • 嗯?为什么线程不起作用?这听起来像是一个非常无效的声明
  • 为什么说Thread需要在return之前终止?
  • 感谢您的快速响应。在这种情况下,线程确实有效。我仍然想到一定的线程进程依赖性。但是线程在返回中幸存下来。

标签: java service methods web return


【解决方案1】:

您需要为此使用线程,因为您将程序流一分为二;返回路径和处理路径是分开的,并排运行。

如果您需要通过方法的返回来发送方法开始的确认,那么为什么您的服务提供方法不能看起来像这样简单?

public Acknowledgement someService() {
  new Thread(new SomeServiceRunnable()).start();
  return new Acknowledgement();
}

服务将被启动,然后方法将返回(从而通知进程已启动),同时处理继续进行,直到线程结束......

我是否在这里遗漏了您需要实现的目标?

希望这会有所帮助。

编辑:

似乎已经设计了一些答案来解决我认为未作为问题一部分提出的问题。以下是我在回答时做出的一些假设,以便阅读此答案的任何人都可以更好地了解它何时可能不适用于他们的特定情况:

这适用于您只想确认服务已从概念上开始执行的情况。确认不能提供有关此执行的任何部分或其初始化是否成功的信息,只能提供概念上已启动的信息,也就是说,关联的 Runnables run() 将在某个时候被调用。

当然,如果您希望执行开始并且调用者返回,那么确认的重要性必然会受到在返回之前等待执行的任务的确切数量的限制,这里没有等待完成并且确认会立即返回,因此无法提供额外信息。

【讨论】:

  • 这是正确答案吗?真的吗?恕我直言,这完全没用,因为您没有承认任何事情。您如何知道 Thread 是否已成功开始处理,还是完全开始了?这仅在您不想在线程代码内部发出信号时才有效,恕我直言,您应该这样做。有了这个,你将返回一个确认而不真正确认任何东西......这与产生线程相同并继续而不关心线程是否已成功开始处理。
  • 正如我所说,这个答案是在 thomelicious 需要通过方法返回发送确认的条件下给出的;他特别说:“[服务应该]在返回确认消息后运行代码”。至于确认它已经开始,为什么我有任何理由不相信 Thread.start() 会起作用?如果它不被信任,恕我直言,它会抛出一个检查异常,如果确实发生了一些不寻常的问题,那么肯定会抛出一个未经检查的异常。线程启动后如何处理失败取决于thomelicious。
  • 好吧,如果'[服务应该]在返回确认消息后运行代码',您的回答并不能保证服务将运行代码。如果线程无法启动怎么办(这里只看最明显的错误)?你错误地返回了一个确认。他还说:“发送了一个确认处理已经开始”。对我来说很清楚。你的回答是完全错误的。我希望当那个代码开始失败时他能想到这一点......
  • 处理怎么可能无法从这里开始?您认为 Thread.start() 在什么情况下会静默失败?如果存在这样的情况,请赐教。 AFAIU Thread.start() 保证将为该线程调用 run()。我没有理由假设 thomelicious 没有任何规定来处理该线程中发生的故障,一旦启动。按照描述问题的方式,“确认”只需要是一个相当空洞的保证,即执行已经开始。我唯一没有回答的是您对问题的解释
  • P.S.请尽量不要对自己的行为如此粗鲁,这应该是一个友好和建设性的社区,是吗?我将编辑我的答案,以澄清我认为您对问题的误解。谢谢你:)。
【解决方案2】:

如何调用客户端的回调方法。 查看工作流程

  1. 调用我的 Web 服务的特定操作(方法)
  2. 开始处理
  3. 在客户端调用方法,发送确认。
  4. 继续处理

【讨论】:

    【解决方案3】:

    你的问题的答案是创建一个线程:

    public boolean beginWorkAndSendAck(){
        Thread t = new Thread(){ 
            public void run(){
                //Do something here
            }
        }
        t.start();
        return true;
    }
    

    在“主”线程消亡后,该线程将继续运行。您可能指的问题是,如果 Web 服务在发送 ack 后关闭进程。线程应该继续运行,因为除非所有线程都完成,否则 java 不会关闭其进程。

    如果它不工作,它可能 Web 服务正在做一些巫术 - 关闭 java 进程或类似的东西。我建议考虑使用 java 创建一个新进程,在这里:http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html 这将需要一个单独的应用程序来执行您需要的工作。

    【讨论】:

    • 与 Elias Vasylenko 的回答相同的错误。
    【解决方案4】:

    线程不起作用,因为线程需要在之前终止 方法的返回。

    错了。线程共享变量,因此可以在线程之间共享数据而无需从线程返回。以你为例:

    调用我的网络服务的特定操作(方法)

    为此产生新线程

    发送一个确认处理已经开始(这是一个返回值)

    不,不要通过返回值来做。新线程向您想要的任何类发送消息(调用方法,更改变量......)。有了这个,你可以向任何你想要的线程发出任何你想要的信号。请注意比赛条件,并在需要时使用“同步”关键字!

    继续处理

    新线程继续处理,主线程也是。

    【讨论】:

    • 关于为什么投反对票或者这纯粹是幼稚的报复的任何 cmets? ;)
    • 我已经解释了我在 cmets 中的位置并编辑了我自己的答案,并首先将它们输入那里,希望我的答案能够防止我认为是一种误解。
    • 在这里重申,更多地关注它如何应用于您的答案:我觉得这是一个过于复杂的问题,并增加了不必要的等待。提问者只想要确认服务已启动,这在概念上(我认为在这里很重要)是通过调用Thread.start() 给出的。如果确认需要包含有关服务执行的某些初始部分是否成功的信息,那么它当然需要等待,最好如您所说从服务线程发送此确认消息,但这是不是问题。
    • 我会再次引用这个问题,也许你没有读到我/他:“发送一个确认处理已经开始”。我看不出我的答案在哪里错了,但我确实看到了你的答案在哪里:你正在返回一个关于线程正在启​​动的确认,而不是处理。而且您的答案也过于复杂,因为您甚至不需要 someService() 方法,也不需要返回新的 Acknowledgment 对象。无用的内存使用。代码膨胀。它什么都不做。
    【解决方案5】:
    Thread t = new Thread(){
        public void run(){
                  //task to complete after sending acknowledge   
        }
    };
    t.start();
    //prepare acknowledgement code and return;
    return new ResponseEntity<>(HttpStatus.OK);
    

    run() 方法中的任务会在返回后继续运行。

    【讨论】:

      【解决方案6】:

      【讨论】:

        猜你喜欢
        • 2017-09-11
        • 1970-01-01
        • 1970-01-01
        • 2018-01-10
        • 1970-01-01
        • 2010-12-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多