java - 我从基于 Java 的 AWS lambda 处理程序启动一个单独的线程,有时会完成,有时不会,为什么?如何保证线程完成?

标签 java multithreading concurrency aws-lambda amazon-dynamodb

从处理程序中,我启动一个单独的线程来更新 Dynamo 表,在其中记录每个用户的 API 调用计数。问题是,处理程序完成后,有时数据库会更新,有时不会,所以我选择使用相同的初始线程进行数据库更新,现在数据库总是更新,所以这意味着另一个线程有时会完成,有时会完成没有。这是否与 lambda 在完成时卡住处理程序调用的方式有关?如何确保单独的线程在处理程序容器被卡住之前完成?我正在使用旧的 Java Runnable 接口(interface)和 Thread 类。

最佳答案

您有两种选择来解决该问题:

  1. Java 方式:假设您在主线程运行时启动一个新线程,您可以在主线程完成时 join() 辅助线程(即,只需在返回之前)。示例:
// Main thread executing...
Thread t = new Thread(
                 new Runnable() {
                     public void run () {
                         //do something
                     }
                  }
    );
t.start(); //Secondary thread starts
// Main thread continues execution
t.join();//Main thread will wait for the secondary to finish
return ...;

这将强制 AWS 保持 lambda 实例处于 Activity 状态,直到所有线程完成为止。它还会损害您的性能,因为您的客户端只有在所有线程完成后才会得到响应。这就引出了第二个选项:

  • AWS 方式:创建一个新的 lambda 函数,其唯一目的是执行单个任务(即更新 DynamoDB)。调用此函数(而不是启动新线程)。您甚至可以异步执行此操作。 有一个很好的例子here使用AWSLambdaAsyncClient 。如果您决定采用 AWS 方式,您也可以通过 SNS 方式:
  •     final AmazonSNSAsyncClientBuilder snsBuilder = AmazonSNSAsyncClientBuilder.standard();
        final AmazonSNS snsClient = snsBuilder.build();
        final PublishRequest pr = new PublishRequest("arn:aws:sns:logging-topic", "<JSON>");
        snsClient.publish(pr);
    

    您的日志记录 lambda 现在可以简单地监听此 SNS 主题。

    关于java - 我从基于 Java 的 AWS lambda 处理程序启动一个单独的线程,有时会完成,有时不会,为什么?如何保证线程完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59034680/

    相关文章:

    java - Dao 注册表重构

    java - 在 Hibernate 中保存大型集合时出现 ConcurrentModificationException

    python - 日志模块的线程安全,网络上的线程安全吗?

    python - 同时解析,python

    java - 您可以在您执行 acquire() 的不同线程上调用 java.util.concurrent.Semaphore.release() 吗?

    java - Spring Integration 中的事务感知 POJO

    java - hibernate 保存奇怪的行为

    java - 再次检查一个列表中的所有内容,导致堆栈溢出

    c# - 使 "modify-while-enumerating"集合成为线程安全的

    c++ - 如何仅在 Concurrency::event 对象现在不处于信号状态时设置它?