어야 나는 항상 내 java-코드에 스레드에 안전하거나능 이유로 그것을 할 경우에만 필요합니까?

StackOverflow https://stackoverflow.com/questions/234341

문제

을 생성하는 경우,클래스에 사용되는 순간 만에서 하나의 스레드,나는 그들이 스레드에 안전 경우에도 필요 없는 것은?그것이 발생 될 수 있는,나중에 이 클래스를 사용하여 여러 스레드에서,그리고 그 시간에 얻을 수있다,경쟁 조건 및 수 있는 힘든 시간들을 찾을지 않은 경우로 만든 클래스는 스레드에 안전하는 첫 번째 장소입니다.거나 만들지 않는 스레드에 안전,성능 향상을 위해?그러나 조화가 악이다.

다르게 물었다:해 내는 클래스 thread-safe 필요한 경우(에서 사용되는 경우 여러 스레드,그렇지 않으면 없음)또는 최적화를 이 문제한 다음 필요하다(참조 하는 경우는 동기화를 먹는 최대의 중요한 부분은 처리 시간)?

도록 선택할 경우,하나의 두 가지 방법이 있습 방법을 줄이는 단점?또는 존재합성,내가 사용하는가?

편집:를 제공하기 위하여 필요한 만큼 보유 이유는 이 질문을 했습니다.에서 우리의 회사는 우리가 작성이 매우 간단한 사용자 관리를 쓰는 데이터를 제공한다.나에 그것을 사용하는 웹사-응용 프로그램과한 후에 그것이 내가 가지고 이상한 오류는 사용자 관리 잊고의 속성에 대한 사용자는(를 포함하여 이름과 암호)에 역할을 수행합니다.는 아주가지만 지속적으로 재현,그래서 그것을 생각했 경쟁 상태입니다.이후 나는 동기화 모든 방법을 읽기와 쓰기에서 디스크에 문제가 사라졌습니다.그래서 저는 생각했죠,내가 아마도 피할 수 있는 모든 어떤 경우,우리는 쓴 클래스와 동기화에서 첫 번째 장소는?

편집 2:로 보 팁의 실제적인 프로그래머,나는 끝#41:항상 디자인에 대한 동시성.이 말하지 않는 모든 코드 스레드에 안전하지만,그것을 말한 디자인이 동시에 마음입니다.

도움이 되었습니까?

해결책

데이터에서 시작하십시오. 명시 적으로 공유되는 데이터를 결정하고 보호하십시오. 가능하다면 잠금을 데이터로 캡슐화하십시오. 기존 스레드 안전 동시 컬렉션을 사용하십시오.

가능할 때마다 불변의 물체를 사용하십시오. 속성을 최종적으로 만들고 생성자에 값을 설정하십시오. "변경"해야하는 경우 데이터가 새 인스턴스를 반환하는 것을 고려하십시오. 불변의 물체는 잠금이 필요하지 않습니다.

공유되거나 스레드가 연결되지 않은 객체의 경우 스레드 안전을 만드는 데 시간을 소비하지 마십시오.

코드의 기대치를 문서화하십시오. JCIP 주석은 사용 가능한 최고의 사전 정의 선택입니다.

다른 팁

나는 실시식을 모두 만들려고 노력했다. 그런 다음 "스레드-안전"의 의미는 사용법에 달려 있음을 깨달았습니다. 당신은 종종 그 사용법을 예측할 수 없으며 발신자는 가지다 어쨌든 스레드 안전 방식으로 사용하려면 조치를 취합니다.

요즘 나는 단일 스레딩을 가정하는 거의 모든 것을 쓰고, 중요한 곳에서 스레딩 지식을 넣습니다.

그러나, 나는 또한 (적절한 경우) 불변의 유형을 만듭니다. 불변의 유형은 자연스럽게 멀티 스레딩에 적합하고 일반적으로 추론하기가 더 쉬워졌습니다.

"가능한 한 간단하지만 더 간단하지는 않지만"의 프린닉을 따르십시오. 요구 사항이 없으면 스레드 안전을 만들어서는 안됩니다. 그렇게하는 것은 투기적이고 불필요 할 것입니다. 스레드 안전 프로그래밍은 클래스에 훨씬 더 복잡해지며 동기화 작업으로 인해 성능이 저하 될 수 있습니다.

객체가 스레드 안전하다고 명시 적으로 언급하지 않는 한, 그렇지 않을 것으로 예상됩니다.

나는 개인적으로 필요할 때 "스레드 - 안전"인 클래스 만 설계 할 것입니다. 필요할 때만 최적화하는 원칙에 따라. Sun은 단일 스레드 컬렉션 클래스의 예와 같은 방식으로 진행된 것 같습니다.

그러나 변경하기로 결정한 경우 어느 쪽이든 도움이되는 몇 가지 좋은 원칙이 있습니다.

  1. 가장 중요한 : 동기화하기 전에 생각하십시오. 나는 "모든 동기화 된 후에는 더 나은 후에는 더 나은 경우" 이것은 잘못되었으며 여러 교착 상태 버그의 원인이었습니다.
  2. 당신의 물건이 불변이 될 수 있다면, 불변으로 만들 수 있습니다. 이것은 스레딩에 도움이 될뿐만 아니라 맵의 키 등으로 세트에서 안전하게 사용하는 데 도움이됩니다.
  3. 객체를 가능한 한 간단하게 유지하십시오. 각각은 이상적으로는 하나의 작업 만 수행해야합니다. 회원의 절반에 대한 액세스를 동기화하고 싶을 수도 있다면 객체를 두 개로 분할해야합니다.
  4. java.util.concurrent를 배우고 가능할 때마다 사용하십시오. 그들의 코드는 99%의 사례에서 당신의 (또는 광산)보다 더 좋고 빠르고 안전합니다.
  5. 읽다 자바의 동시 프로그래밍, 그것은 훌륭합니다!

측면 비고와 마찬가지로 : 동기화! = 스레드 안전성. 그럼에도 불구하고 동시에 데이터를 수정하지는 않지만 동시에 데이터를 읽을 수 있습니다. 따라서 동시에의 동시 수정을 보호 할뿐만 아니라 모든 스레드에서 데이터를 신뢰할 수있게하는 동기화를 의미하는 Java 메모리 모델을 명심하십시오.

그렇습니다. 제 생각에는 스레드 안전성이 처음부터 바로 내장되어 있어야하며 동시성 처리가 필요한 경우 응용 프로그램 논리에 따라 다릅니다. 아무것도 가정하지 말고 시험이 괜찮은 것처럼 보이지만 인종 조건은 잠자는 개입니다.

나는 찾았다 JCIP 주석은 어떤 클래스가 스레드 안전인지 선언하는 데 매우 유용합니다. 우리 팀은 수업에 주석을 달았습니다 @threadsafe, @notthreadsafe 또는 @immutable. 이것은 Javadoc을 읽는 것보다 훨씬 명확하며 FindBugs @immutable의 위반을 찾도록 도와줍니다 @guardedby 계약도.

코드의 어떤 세그먼트가 멀티 스레드와 그렇지 않은지 절대적으로 알아야합니다.

멀티 스레드의 영역을 작고 제어 가능한 섹션에 집중할 수 없다면 성공하지 못할 것입니다. 멀티 스레드 인 앱의 일부는 다중 스레드 환경에 대해 신중하게, 완전히 분석, 이해 및 조정해야합니다.

나머지는 그렇지 않으므로 스레드-안전을 만드는 것은 폐기물이 될 것입니다.

예를 들어, Swing Gui를 사용하면 Sun은 그 중 어느 것도 멀티 스레드가 될 것이라고 결정했습니다.

아, 그리고 누군가가 당신의 수업을 사용한다면-스레드 섹션에 있다면 스레드 사프를 만들 수 있습니다.

Sun은 처음에 ThreadSafe Collections (Only)와 함께 나왔습니다. 문제는, ThreadSafe는 성능 목적을 위해 스레드 스페이프를 만들 수 없다는 것입니다. 이제 그들은 래퍼가있는 비 스레드 스페이프 버전으로 나왔습니다. 대부분의 경우, 래퍼는 불필요합니다. 스레드를 직접 만들지 않는 한 클래스가 스레드 사프가 될 필요는 없지만 Javadocs에서 문서화하십시오.

여기에 나 개인적인 접근 방식:

  • 물 및 데이터 구조 변경할 수 없 어디든지 당신은 할 수 있습니다.는 일반적으로 좋은 연습,그리고 자동으로 스레드에 안전합니다.문제를 해결합니다.
  • 해야 하는 경우 객체를 변경할 수 일반적으로 다음 지 않을 귀찮게 만들려고 노력하는 스레드를 안전.을 위한 추론 이것은 간단하다:이 있을 때 변경 가능 상태가 다음을 잠그기/제어 할 수 없이 안전하게 처리하여 단일 클래스입니다.심지어 동기화하면 모든 방법이 보장하지 않는 스레드에 안전합니다.를 추가하면 동기화하는 객체만 가져옵에서 사용되는 하나의 스레드 컨텍스트에,당신은 단지 추가 불필요한 오버헤드가 발생합니다.수도 있습니다 그래서 뿐만 아니라 그것을 떠날자/구현하는 사용자에게 최상 잠금 시스템이 필요합니다.
  • 제공하는 경우에는 높은 수준의 공개 API 다음 무엇을 구현을 잠그하는데 필요한 API 스레드를 안전.높은 수준에 대한 기능의 오버헤드 스레드에 안전이 아주 사소한,그리고 귀하의 사용자가 확실히 감사합니다.API 를 가진 복잡한 동시성 의미가 있는 사용자가 필요한 작업은 주변에 좋은 API!

이 방법은 제공되는 나를 넘는 시간::필요할 수 있습니다 가끔 예외가 있지만 평균적으로 매우 좋은 장소를 시작합니다!

Java API에서 Sun이 한 일을 따르고 싶다면 컬렉션 클래스를 살펴볼 수 있습니다. 많은 일반적인 컬렉션 클래스는 스레드 안전이 아니지만 스레드 안전 대응 물이 있습니다. Jon Skeet (의견 참조)에 따르면, 많은 Java 클래스는 원래 스레드 안전 이었지만 개발자에게 도움이되지 않았으므로 일부 클래스에는 두 가지 버전이 있습니다. 하나는 스레드-안전하고 다른 하나는 스레드 안전이 아닙니다.

내 조언은 스레드 안전과 관련된 오버 헤드가 있기 때문에 필요할 때까지 코드 스레드 안전을 만들지 않는 것입니다. 나는 이것이 최적화와 같은 범주에 속한다고 생각합니다.

여러 스레드에서 사용할 클래스를 별도로 설계하고 단일 스레드에서만 사용할 다른 스레드를 문서화합니다.

단일 나사산은 작업하기가 훨씬 쉽습니다.

멀티 스레드 로직을 분리하면 동기화를 올바르게 만드는 데 도움이됩니다.

"항상"는 소프트웨어 개발에서 매우 위험한 단어입니다. 이와 같은 선택은 "항상"상황입니다.

인종 조건을 피하려면 하나의 객체 만 잠그십시오 - 인종 조건에 대한 설명을 지식으로 읽으면 크로스 잠금 장치 (레이스 조건은 오해 - 레이스가 중단됩니다)는 항상 2 + 스레드가 잠그려고하는 결과입니다. 두 + 객체.

모든 방법을 동기화하고 테스트를 수행하십시오 - 실제로 문제를 처리 해야하는 실제 앱의 경우 동기화가 적은 비용입니다. 그들이 당신에게 말하지 않는 것은 모든 것이 16 비트 포인터 테이블에서 잠금을한다는 것입니다 ... 그 시점에서 당신은 uh입니다.

버거 플립 핀 이력서를 최신 상태로 유지하십시오.

클래스를 생성하는 경우, 현재 단일 스레드에서만 사용되는 클래스를 만들려면 스레드-안전을해야합니다.

스레드에서 사용하는 클래스는 프로그램 전체가 스레드 안전을 위해 스레드-안전을 위해 스레드-안전을 위해 필요하지 않습니다. 스레드간에 비 "스레드 안전"클래스의 객체를 안전하게 공유 할 수 있습니다. 만약에 적절한 동기화로 보호됩니다. 따라서 클래스 자체가 분명해질 때까지 스레드 안전을 만들 필요가 없습니다.

그러나 멀티 스레딩은 프로그램에서 근본적인 (건축) 선택입니다. 그것은이다 실제로 생각으로 추가 할 것이 아닙니다. 따라서 처음부터 수업이 스레드 안전 해야하는지 알아야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top