2012-01-30 3 views
2

번역기를 쓰고 있는데 번역자가 사용하는 상당수의 Java 문자열 리터럴이 있습니다. 나 자신의 non-blocking threadsafe tokenizer를 가지고있다. 이것은 어려운 작업을위한 java.util.regex.Matcher보다 빠르며 Matcher 클래스와 달리 immutable이기 때문에 나의 tokenizer/Matcher는 여러 스레드 사이에서 불변의 final 클래스처럼 공유 될 수있다. 번역을하고있다.비 스레드 안전 문자열 변형 및 정적 초기화 자 internationing

matcher 클래스에는 CharSequence와 같은 전문화 된 문자열 형 클래스가 필요하지만 내 토크 나이저로 조정됩니다. java.lang.String에서 생성 된 my sequence/stringvariant의 하위 클래스 중 하나는 변경되지 않으므로 여러 스레드가 공유하는 단일 번역기 싱글 톤은 String을 MyString에 매핑하는 내부 해시 맵을 갖습니다. 필자는 불변의 토크 나이저에서 사용되는 불변의 문자열 변형을 인턴하고 싶다. 왜냐하면 많은 리터럴이 동일하기 때문이다.

그래서 하나의 인턴쉽 해시 맵이 있지만 불행히도 다른 여러 클래스의 정적 초기화 프로그램에 의해 추가되므로 스레드되지 않은지도처럼 들릴 수 있습니다. 어떻게하면이 인터내셔날지도가 도착하지 않고 점진적으로 구축 할 수 있습니까? 또한 non-blocking 동시 해시 맵을 사용하고 싶지 않습니다. 목표, 그냥 평범한 HashMap.

앤디

+1

_why_ 스레드 안전하지 않은 문자열을 원하십니까? 문자열을 변형 할 수 있어야하므로 'StringBuilder'를 살펴보십시오. 그렇지 않으면'String' 만 사용하십시오. 또한 Java에서 문자열은'intern()'메서드를 호출하지 않는 한 컴파일 중에 만 인턴됩니다. 대다수 문자열에는 권장되지 않습니다. 'this.map = this.map'을 쓰는 것은 컴파일러에 의해 최적화 될 가능성이 높습니다. 그리고 어쨌든 당신이 원하는 것을하지 않을 것입니다. _map_에 대한 참조는 volatile입니다. 'SynchonizedMap'을 끝내면'UnmodifiableMap'을 랩핑합니다. –

+0

자신의 문자열 클래스를 작성하는 것은 코드 냄새가 아닙니다. 코드 악취입니다. –

+0

매우 구체적인 질문을하고 있습니다. 당신이 이것을 원한다면 무엇을하려고 하는가? "쓰레드 안전하지 않은 문자열 변형"의 목적은 무엇입니까? – Gray

답변

0

가 여러 다른 종류의 정적 초기화가 첨가되고,

"Initialization Problems for Java"

따르면 적어도 자바 6에서는, 문제

Java에서 동시 초기화로 교착 상태가 발생할 수 있습니다. 두 개의 스레드가 두 개의 다른 클래스를 동시에 초기화하고 두 스레드가 다른 클래스의 구성 요소를 처음으로 활성 사용을 감지하면 두 스레드 모두 다른 스레드가 해당 초기화를 시작하기를 대기하기 때문에 두 스레드가 모두 차단됩니다.

따라서 클래스 초기화 잠금은 클래스마다 있으며 과도 초기화를 신뢰할 수 있지만 두 개의 다른 클래스를 동시에 초기화 할 수 있습니다.

값을 많이 넣는 경우 또는 많은 독자가있을 수 있지만 작성자가 적을 경우 필드에 할당하는 것이 원자 적이므로 대체하여 mutex 내에서 쓰기 및 바꾸기를 수행 할 것입니다. ConcurrentMap을 사용합니다.