2011-07-27 3 views
5

스레드 A에서 스레드 B를 죽이려고 시도 할 때마다 (여전히, 때로는 효과가있었습니다) 안드로이드 응용 프로그램에서 아직 알려지지 않은 몇 가지 이유로 잠그고있는 스레드에 문제가있었습니다. 내 메서드 중 일부는 동기화되지 않고 스레드간에 호출을 만들기 때문에 그것은 것 같았다. 나는 cancel 메소드와 본질적으로 이벤트 핸들러가 동기화 된 메소드를 만들었으며 몇 가지 공유 변수를 휘발성으로 만들고 모든 것이 작동했습니다.Java에서 메소드를 동기화하여 선언문을 사용하여 거래합니까?

내가 추가 한 이상한 휘발성/동기화 된 선언 20 개 중 어느 것이 실제로 문제를 해결했는지 모르겠다. 그리고 그 생각은 "내가 신경 써야할까요? 효과가 있습니다.

그럼, 내 질문은 : 동기화 또는 원시 휘발성 선언과 관련된 트레이드 오프가 있습니까? 필요없는 경우 이러한 선언을 피할 수있는 이유가 있습니까? 문제

편집
스레드 (들) AsyncTask를 다른 작업자 스레드 형 솔루션은 잘 작동하지 않도록,/수신 스트리밍 데이터를 전송하는 블루투스 연결입니다. 그들은 유한 작업을 수행하고 완료되면 종료하도록 설계되었습니다. ASyncTask와 마찬가지로 앱을 죽이는 많은 오버 헤드가 추가됩니다. 이와 같이 지속적으로 실행되는 스레드의 경우 스레드를 사용하는 것이 여전히 최선의 방법입니다.

나는 안드로이드 디자인 패러다임을 따르기 위해 안드로이드 Service을 사용하여 스레드를 생성하고 관리합니다.

+0

(작은?) 고유 한 성능 패널티가 있습니다. "스레드 잠김 문제"(비 휘발성 멤버 필드 폴링)가 무엇인지 알기는 어렵지만 데드락을 얻는 좋은 방법처럼'synchronized '소리를 자유롭게 추가하는 것, 그리고 앱이 어떻게되는지를 어떻게 알 수 있습니까? 경쟁 조건이 없다.큰 문제는 스레드간에 공유 상태가 * 많이 * 있습니다. 공유해야 할 대상을 결정하고, 공유 상태가 스레드 안전 (가능한 불변의 도움을 줌)인지 확인하고, 스레드가 통신하는 방법을 결정해야합니다 (Handler/ConcurrentLinkedQueue/LinkedBlockingQueue?). –

답변

-1

작동하는 경우 지금 해결하지 마십시오. :)하지만 다음 프로젝트에서는 AsyncTask을 사용해야합니다. Dev Guide. 나는 성능상의 영향이 Android 컨텍스트에서는 실제 관심사가 아니라고 생각하지만 복잡성, 가독성 및 향후 유지 관리 가능성이 문제가 될 수 있습니다 (스레드/취소 스레드, 많은 공유 변수).

+0

ASyncTask에 대해 알고 있지만 지속적으로 실행되는 스레드가 필요한 Bluetooth 통신 응용 프로그램입니다. ASyncTask는 안정된 연결이 아닌 미래의 유한 한 시간에 종료 될 단일 태스크를 의미합니다. ASyncTask는 훌륭하지만 마술 총알이 아닙니다. – CodeFusionMobile

+0

죄송합니다. 어디에서 사용했는지 모르겠지만 '20 괴상한 휘발성/동기화 됨 '을 기반으로 한 것은 여전히 ​​Java 프로그램에서 매우 복잡합니다. – user802421

+2

백그라운드 블루투스 통신의 경우 진행중인 서비스로 사용하지 않아야합니까? Android 시스템에서 서비스의 스레드를 관리하도록하고 애플리케이션에서 서비스와 대화하게하십시오. – fluffy

4

내 경험에 의하면, 특정 객체에 대한 액세스에 synchronized (객체) {...}를 사용하여 가능한 한 세밀한 수준에서 잠금을 수행하는 것이 일반적으로 더 쉽고 더 자주 수행됩니다. 또한 동시에 획득해야하는 잠금이 여러 개있는 경우 항상 같은 순서로 획득해야합니다.

정적 메서드에는 별다른 문제가 없어 걱정할 필요가 없습니다. 동기화 된 인스턴스 메서드는 전체 클래스가 아닌 해당 인스턴스에만 동기화되므로 인스턴스 메서드에서 둘 다 동기화해야하는 경우 synchronized (this.class) {..와 같은 작업을 수행해야합니다. .}뿐만 아니라, 위의 경우 적용하는 경우, 정말 당신이 특정 메서드에서 액세스하는 정적 필드를 통해 synchronized() 할 것입니다.

일반적으로 사용자는 자신의 스레드를 생성하지 않고 스레드 관리를 위해 시스템의 기존 메커니즘 (예 : 진행중인 작업 대기열의 경우 ThreadPoolExecutor, 비동기 UI 업데이트의 경우 AsyncTask)을 사용해야합니다. . ThreadPoolExecutor는보다 성능이 좋고 (멀티 코어 장치를보다 잘 활용할 수 있습니다.) UI에 일을하려면 몇 가지 추가 작업을해야합니다. 반면 AsyncTask는 조금 느리고 헤비급 경향이 있지만 UI 스레드에서 onPostExecute 콜백도 실행합니다.

+0

이러한 모든 메소드 (ThreadPool, ASyncTask 등)는 작업이 완료 될 때 종료되는 작업 또는 무거운 프로세싱의 일부 형식을 실행하도록 설계되었습니다. 나는 활성 블루투스 연결을 관리하고 수십 개의 서로 다른 데이터 패킷을 보내고 연결 상태와 변수를 많이 모니터링하고 있습니다. 이와 같은 비 종결 프로세스의 경우 ASyncTask 및 작업자 스레드가 적절한 선택이 아닙니다. – CodeFusionMobile

+0

오케이. 세 번째 단락은 일반적으로 편집자의 질문과 관련이 없지만 일반적으로 염두에 두어야 할 사항입니다. – fluffy

관련 문제