복붙노트

[SPRING] RestTemplate은 스레드로부터 안전한가요?

SPRING

RestTemplate은 스레드로부터 안전한가요?

Spring RestTemplate은 쓰레드에 안전한가요? 그건

해결법

  1. ==============================

    1.RestTemplate은 스레드로부터 안전합니다 (강조 표시됨).

    RestTemplate은 스레드로부터 안전합니다 (강조 표시됨).

    RestTemplate 클래스의 객체는 HTTP를 처리하기 위해 상태 정보를 변경하지 않습니다. 클래스는 연결 객체와 같지 않고 전략 디자인 패턴의 인스턴스입니다. 상태 정보가 없으면 RestTemplate 객체를 공유하는 다른 스레드가 상태 정보를 손상 시키거나 경합 할 가능성이 없습니다. 이것이 스레드가 이러한 객체를 공유 할 수있는 이유입니다.

    RestTemplate의 소스 코드를 살펴보면 객체 생성 후 스레드 안전성을 제공하기 위해 동기화 된 메서드 나 휘발성 필드를 사용하지 않는다는 것을 알 수 있습니다. 따라서 RestTemplate 객체를 생성 한 후 수정하는 것은 안전하지 않습니다. 특히 메시지 변환기를 추가하는 것은 안전하지 않습니다.

    메시지 변환기 목록을 제공하려면 다음 중 하나를 수행해야합니다.

    첫 번째 경우는 개체를 만들 때 메시지 변환기를 설정하는 유일한 방법이므로 "일단 스레드가 생성되면 안전합니다"라고 말하는 것이 옳습니다.

    클래스는 Spring Framework의 일부이므로 대부분의 실제적인 경우 클래스의 객체는 첫 번째 (생성자를 사용하는 종속성 삽입) 또는 두 번째 (설정자를 사용한 종속성 삽입)를 사용하여 Spring 응용 프로그램 컨텍스트의 일부로 설정됩니다. 메서드 등을 여러 스레드에 안전하게 게시 할 수 있습니다.

  2. ==============================

    2.라이브러리의 관점에서 스레드로부터 안전합니다. 예를 들어, getMessageConverters ()는 public입니다. 즉, 누군가가 목록을 보류하고 라이브러리의 목적을 벗어나 수정하면 문제가 발생할 것입니다 (RestTemplate 인스턴스 생성 후 어느 순간에 호출되는 경우 setter 메소드조차도). - 그리고 다른 스레드가 분명히 사용하는 동안, 붐!). 아마 Ross에 무슨 일이 일어 났을까요? (대답에 대한 답변은 충분하지 않지만 thread-safe 및 thread-safe 인수를 모두 백업하고 있습니다)

    라이브러리의 관점에서 스레드로부터 안전합니다. 예를 들어, getMessageConverters ()는 public입니다. 즉, 누군가가 목록을 보류하고 라이브러리의 목적을 벗어나 수정하면 문제가 발생할 것입니다 (RestTemplate 인스턴스 생성 후 어느 순간에 호출되는 경우 setter 메소드조차도). - 그리고 다른 스레드가 분명히 사용하는 동안, 붐!). 아마 Ross에 무슨 일이 일어 났을까요? (대답에 대한 답변은 충분하지 않지만 thread-safe 및 thread-safe 인수를 모두 백업하고 있습니다)

  3. ==============================

    3.좋아, 내가 소스 코드에서 이러한 문제를 일으키는 오래된 코드를 파고 수도 있습니다.

    좋아, 내가 소스 코드에서 이러한 문제를 일으키는 오래된 코드를 파고 수도 있습니다.

    다른 스레드가 내부 컬렉션을 수정할 수있는 환경이 존재하는 경우에도 동기화를 수행한다고해도 좋을 것이라고 생각합니다. 그래서 조심해야합니다. 이전 코드를 살펴보면 실제로 메시지 변환기를 사용하고있었습니다. 그러나 생성시에만 동기화됩니다.

    restTemplate = new RestTemplate();
    
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());
    

    그 후 RestTemplate과의 유일한 상호 작용은 다음과 같습니다.

    return restTemplate.postForObject(url, object, clazz);
    

    이것은 결국 예외를 던지는 행이기도합니다.

    물론 메시지 변환기와의 상호 작용은 없습니다 (우리는 그것에 대한 로컬 참조가 없습니다).

    stacktrace 및 스프링 소스 코드를 보면이 줄에서 오류가 발생했습니다.

    for (HttpMessageConverter<?> converter : getMessageConverters()) {
    

    그래서 우리는 무엇을 가지고 있을까요?

    요약하면, 메시지 변환기로 직접 놀고 싶다면 상황이 스레드로부터 안전하지 않을 수도 있습니다. 이 경우는 이상한 일이지만, 게시하는 것이 유용 할 거라고 생각했습니다.

  4. ==============================

    4.위의 허용 된 대답에 동의하지 않으려면 (강조가 추가됨) 싫지만 스레드 안전은 없습니다. 창조 후에도. 내부적으로 ArrayLists로 놀고있다. 나는 소스를 파고 들지 않았다. 나는 이것들을 너무 많이 보았다.

    위의 허용 된 대답에 동의하지 않으려면 (강조가 추가됨) 싫지만 스레드 안전은 없습니다. 창조 후에도. 내부적으로 ArrayLists로 놀고있다. 나는 소스를 파고 들지 않았다. 나는 이것들을 너무 많이 보았다.

    java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
    at java.util.ArrayList$Itr.next(ArrayList.java:831)
    at org.springframework.web.client.RestTemplate$AcceptHeaderRequestCallback.doWithRequest(RestTemplate.java:677)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:567)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545)
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:253)
    
  5. from https://stackoverflow.com/questions/22989500/is-resttemplate-thread-safe by cc-by-sa and MIT license