Java 这个基于Apache的API客户端类是线程安全的吗?
这是一个非单例类,用于向API发送有效负载Java 这个基于Apache的API客户端类是线程安全的吗?,java,multithreading,concurrency,apache-httpclient-4.x,Java,Multithreading,Concurrency,Apache Httpclient 4.x,这是一个非单例类,用于向API发送有效负载 class MyApiClient { String url = "http://www.yankeeService.com" int playerId = 99 String playerFirstName = "Aaron" String playerLastName = "Judge" public void sendPayload(String content) { CloseableHttpClient cl
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是一个局部变量,因此每个线程都将获得其自己的版本,并且一个线程没有机会获取另一个线程的有效负载内容,对吗?,而您提出的方法存在多个问题(什么是
”)“
,您真的想手工制作JSON对象,并且不处理异常吗)您对并发性的评估似乎是正确的
不过,您可能希望确保这一点,如果您的变量不应该被更改,那么可以将其设置为最终变量。这样,如果将来的代码修改确实导致它们被更改,您将在编译时知道存在错误。或者这不是一个错误,这些变量需要改变。。。但您将知道必须重新考虑并发问题。是的,它是线程安全的。您正在尝试将某些内容发布到远程位置。似乎您并不担心人们在远程位置覆盖内容(如果您担心,那么即使线程安全逻辑也不会帮您) 您的逻辑“我认为这很好,因为没有任何全局变量以任何方式被修改(它们是只读的,用于促进API调用)。” 这是正确的
出于可读性和约定目的,我建议使用带有属性的最终构造。当线程以不受控制的方式使用和写入共享数据时,就会出现多线程问题 意思是:
- 当所有线程都仅调用send方法时,您就不会有问题,因为所有线程都在读取和使用相同的数据
- 但是,当这些线程更改任何字段的内容时,所有赌注都被取消
- 首先,将这些字段设置为私有,以便从外部隐藏此类详细信息
- 考虑让它们成为最终版本
类MyApiClient{
私有静态最终HttpRequest HTTP\u请求=
HttpRequestBuilder.createGet(“http://www.yankeeService.com")
.addContentType(ContentType.APPLICATION_JSON)
.build();
int playerId=99
弦乐演奏者firstname=“亚伦”
字符串播放器lastname=“Judge”
公共无效发送有效负载(字符串内容){
字符串jsonPayload=“”{“id”:“$playerId”,“name”:“$playerLastName”,“DailReport”:“$content”}”;
断言(HTTP_REQUEST.executeWithBody(jsonPayload.getStatusCode(),equalTo(200));
}
}
HTTP_请求是线程安全的如何声明方法
已同步
?除了声明varsfinal
(这是我喜欢的方法)之外,这还有什么作用吗?还有什么是HttpClients.createDefault()
在后续调用中返回相同的对象,它使用以前调用中的缓存数据?synchronized
将添加额外的保护层,但是你没有使它成为线程安全的——你只是使它成为单线程的——尽管所有单线程的东西都是线程安全的,但是它们不能扩展。既然已经是线程安全的,为什么还要将自己限制在一个同步的代码块上呢?如果要使用synchronized,不要在方法上同步,而是在私有对象上同步。同步该方法会导致使用对象的监视器,并可能导致饥饿。@两栖和HttpClients.createDefault()
将创建一个新实例,这就是它专门使用create的原因。它是线程安全的。这实际上是从Groovy代码中提取的,这就是为什么JSON负载是这样创建的,以防有人怀疑。
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));
}
}