这个基于Apache的API客户端类线程是否安全?

时间:2017-08-21 15:36:00

标签: java multithreading concurrency apache-httpclient-4.x

这是一个非Singleton类,用于将有效负载发送到API ...

class MyApiClient {

  String url = "http://www.yankeeService.com"
  int playerId = 99
  String playerFirstName = "Aaron"
  String playerLastName = "Judge"

  public void sendPayload(String content) {

    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost();

    String jsonPayload = """ "{"id":"$playerId","name":"$playerLastName","dailyReport":"$content"}" """ ;
    StringEntity entity = new StringEntity(jsonPayload);
    httpPost.setEntity(entity);

    CloseableHttpResponse response = client.execute(httpPost);
    assertThat(response.getStatusLine().getStatusCode(), equalTo(200));
    client.close();

 }

}

如果多个线程要输入 sendPayload 方法会有任何问题吗?

我认为没问题,因为没有任何全局变量以任何方式被修改(它们是只读的并用于促进API调用)。

jsonPayload 也是一个局部变量,因此每个线程都会得到它们自己的版本,并且一个线程没有机会获取另一个线程的有效负载内容吗?

4 个答案:

答案 0 :(得分:1)

是的,它是线程安全的。您正尝试将某些内容发布到远程位置。看起来你并不担心人们会覆盖远程位置的内容(如果你那么,即使是线程安全逻辑也不会是你的帮助)

你的逻辑"我认为没关系,因为没有任何全局变量以任何方式被修改(它们是只读的并用于促进API调用)。"  是对的。

出于可读性和惯例的目的,我建议使用带有属性的final构造。

答案 1 :(得分:1)

线程使用以不受控制的方式共享数据时,会出现多线程问题。

意义:

  • 当所有线程调用send方法时,您就没有问题 - 因为所有线程都在读取并使用相同的数据
  • 但是当这些线程更改任何字段的内容时 - 所有投注都会关闭。

事情是:您的字段具有包可见性 - 这意味着从“外部”更新它们非常简单。如果字段内容发生更改,MyApiClient的对象甚至不会注意

因此:

  • 首先,将这些字段设为私有隐藏来自外部的此类详细信息
  • 考虑让它们最终成为

答案 2 :(得分:0)

虽然问题范围之外的问题超出了您提出的方法(""",但您是否真的希望手工制作JSON对象,而不是处理异常)你的并发评估似乎是正确的。

但是,您可能希望确保,如果它们不应该被更改,可能会使您的变量成为最终变量。这样,如果将来的代码修改确实导致它们被更改,那么您在编译时就会知道存在错误。或许它不是一个错误,这些变量需要改变......但你知道你必须重新审视你的并发问题。

答案 3 :(得分:0)

您可以使用基于apache http api构建的http请求。文档here

class MyApiClient {
    private static final HttpRequest<?> HTTP_REQUEST =
            HttpRequestBuilder.createGet("http://www.yankeeService.com")
                    .addContentType(ContentType.APPLICATION_JSON)
                    .build();

    int playerId = 99
    String playerFirstName = "Aaron"
    String playerLastName = "Judge"

    public void sendPayload(String content) {

        String jsonPayload = """ "{"id":"$playerId","name":"$playerLastName","dailyReport":"$content"}" """ ;
        assertThat(HTTP_REQUEST.executeWithBody(jsonPayload).getStatusCode(), equalTo(200));

    }
}

HTTP_REQUEST是线程安全的