2013-08-04 5 views
4

Java Spring MVC 프로젝트를 개발 중이며 Java Spring Bean에서 인스턴스 변수를 사용하는 것을 망설이고 있습니다.이 주제에 대해 질문하고 싶습니다.Java Spring Bean의 인스턴스 변수

Java Spring Bean에서 인스턴스 변수를 사용했으며 유형이 String입니다.

private String abc = "hell"; 

알다시피 Java Spring 기본 범위는 Singleton이며 프로젝트의 시작 시점에 생성됩니다. 이것은 단일 인스턴스이며 내 인스턴스 변수는 스레드로부터 안전해야합니다.

빈의 메소드에서이 변수 "abc"를 사용하고 여러 스레드가이 변수에 도달하면 각 스레드의 데이터 일관성이 손상됩니까?

예를 들어, 스레드 1은 빈에 도달하여 abc 변수를 "hello"로 변경했습니다. 그 시간에 스레드 1 참조가 abc 변수 포인트 "hell"또는 "hello"입니까? 나는이 주제에 대해 혼란스러워한다.

ThreadLocal 개체는 각 스레드가 자신의 abc 변수를 보유하도록 제공합니다. 그러나 나는 ThreadLocal 개체를 사용하여 Tomcat의 메모리 누수가 발생한다는 것을 읽었습니다. Tomcat의 7.0 버전 이후에는 고정되어 있다고합니다 .

각 스레드는 자신의 변수를 보유하고 있기 때문에 작업이 끝나면 container.But에 의해 관리되는 스레드 풀을 반환하므로 풀을 반환하면 ThreadLocal 객체가 파괴되지 않고 메모리 누수가 발생합니다.

또한 String 객체는 이론적 인 관점에서 볼 때 불변이므로 다중 스레드 문제가 발생합니까 ??

각 스레드가 자체적으로 String 변수를 보유하고 있습니까? 예를 들어, 스레드 1 트리거 및 다음 메서드 호출을 시작하고 별도의 문자열 변수 "abc"및 스레드 2 트리거를 만든 다음 새 문자열 변수 "abc"만들고 "abc"변수를 서로 손상합니까?

나는이 사용법의 개념에 대해 정말로 궁금해하고 답을 배우고 싶어합니다.

답변

4

별도로 질문을 보내 드리겠습니다.

나는이 변수 콩의 방법에 abc하고 여러 스레드에 의해 도달 할 때 데이터 각 스레드의 일관성을 손상시킬 수를 사용?

이 질문에 대한 짧은 대답은 '예'입니다.abc의 값이 Thread 인 경우 일 수도 있고이 아닌 다른 값일 수도 있습니다. 이것이 volatile 키워드가 도입 된 이유입니다.

나는 당신이 다음 동기화 및 volatile의 사용에주의가 필요 Spring에서 변경할 수 싱글 콩을 갖고 싶어.

String은 변경할 수 없으므로 데이터가 "손상"되지 않습니다. 그러나 하나의 스레드가 다른 스레드가 abc 값을 변경 한 것을 볼 수 없습니다.

따라서 변수가 abc입니다.

  1. abc = "안녕하세요."
  2. 스레드 1은 abc을 "안녕"으로 읽습니다.
  3. 스레드 1이 기준에 작성하여 abc 변경 : abc="Hello."
  4. 스레드 2 abc을 읽고, 그것을 abc 읽기 여부 불분명하다 "안녕." 또는 "안녕하세요."

나는의 ThreadLocal 객체에 문자열 abc 방송 변수는 각 스레드는 각 스레드 변수의 다른 인스턴스을받을 수있는 데 사용됩니다

ThreadLocal 변수 자신의 ABC를 보유하고 제공 할 수 있습니다. 이것은 웹 서버가 스레드 사전 요청 모델을 사용하므로 웹 서버의 스레드와 상태를 연결하는 데 종종 사용됩니다.

톰캣 7 수정 ThreadLocal 누출 문제. 스레드에서 설정 한 변수를 제거하지 않으면 이됩니다. 또는 요청이 다른 요청의 컨텍스트에서 항목을 가져옵니다. 스레드가 ThreadLocal에 컨텍스트가있는 풀에 체크인 된 다음 다른 요청에 의해 체크 아웃 될 때 발생합니다.

톰캣 7에서는 이러한 문제를 감지하고 스레드를 바꿔 ThreadLocal 개의 변수를 삭제합니다. 이는 값이 비싸기 때문에 ThreadLocal을 올바르게 사용하면 피할 수 있습니다.

서블릿 필터에서 ThreadLocal 개의 변수를 삭제해야합니다.

그래서 :

당신은 당신이 당신이 ThreadLocal을 사용할 수있는 하나 개의 스레드와 다른 스레드에서을 보였다하지 않는 그 변화 에 대해 쓰고 싶은 변수 abc을 가지고,하지만 당신은 할 필요가있는 경우 각 요청 후에 상태를 지우는 데 매우주의하십시오.

당신이 요 하나 개의 스레드에서 그 변화 을 위해 쓰기 할 변수 abc이있는 경우

는 다른 스레드에서 다음 당신이 volatile 변수로 싱글 톤 bean을 사용할 수 있습니다 볼 수 있습니다.

+0

하나의 메소드에서 ThreadLocal 객체를 사용하며이 메소드는 JSP에 의해 호출됩니다. 메소드의 첫 번째 행은 ThreadLocal 객체 세트의 메소드 매개 변수 값을 취합니다. "하지만 각 요청 후에 상태를 지우는 데 매우주의해야합니다." 나는이 문장을 제공하고 내가 올바르게 이해하면 괜찮았다. 메모리 누출이 발생하면, 나는 ThreadLocal 객체에 대한 서블릿 필터를 작성할 것이다. 맞습니까? –

1

인스턴스 변수가 Singleton 인 빈의 범위를 정의하는 경우 귀하의 경우에 맞춰야합니다.

Spring reference document에 따르면, 아래는 Singleton Scoped Bean에 대한 정의입니다.

To put it another way, when you define a bean definition and it is scoped as a singleton, 
the Spring IoC container creates exactly one instance of the object defined by that bean 
definition. This single instance is stored in a cache of such singleton beans, and all 
subsequent requests and references for that named bean return the cached object. 

Singleton

은 콩 당신이 지정하지 않은 경우에 투입 될 기본 범위입니다.

또한 Spring의 bean 범위 접근법을 사용하여 케이스를 처리하려고 할 경우 아래 진술서를 명심해야합니다.

This approach is powerful and flexible in that you can choose the scope of the objects 
you create through configuration instead of having to bake in the scope of an object at  
the Java class level. 
+0

이것은 어떻게 OP 스레드 안전성 문제에 정확하게 대답합니까? –

+0

@BoristheSpider 하나의 bean 정의를 객체 인스턴스의 수만큼 처리하는'prototype'과는 달리, 'Singleton' scope 단일 Bean 정의를 Spring IoC 컨테이너 당 하나의 객체 인스턴스로 범위 지정합니다. 범위로 생성 된 _ 개체 인스턴스 수로 이동합니다. –

+0

우선 답장을 보내 주셔서 감사합니다. Vikas V. 예를 들어, 스레드 1은 bean에 도달하여 abc 변수를 "hello"로 변경했습니다. 그 시간에 스레드 2 참조가 abc 변수 포인트 "hell"또는 " 여보세요"? 나는이 주제에 대해 혼란스러워한다. –

관련 문제