2011-02-03 4 views
0

Handler에 게시 된 Runnable 객체 병합을위한 디자인 개념에 대한 조언이나 비평을 찾고 있습니다. 이 경우에는 이벤트 스레드에서 수행해야하는 작은 작업 단위를 생성하는 백그라운드 스레드가 있습니다. 각 청크는 일반적인 방법으로 Runnable로 처리기에 게시됩니다. 이러한 Runnable 중 하나가 실행을 시작하지 않은 경우 다른 Runnable을 작성 및 게시하는 대신 실행될 때 추가 작업을 수행하도록 수정하는 것이 쉽습니다. 이 작업 청크의 병합은 다른 Runnable을 구성하는 것보다 비용이 적게 듭니다. 또한 백그라운드 스레드가 이벤트 대기열에 범람하는 문제를 줄여줍니다.디자인 문제 : Handler에게 보내진 객체 합치기

그러나 몇 가지 문제가 있습니다. 우선, 이벤트 큐에 전달 된 마지막 Runnable에 대한 액세스 권한이 필요합니다. 지금까지 내가 아는 한, Handler 나 Looper는 그러한 함수를 제공하지 않기 때문에 백그라운드 스레드 코드에 마지막으로 게시 된 Runnable에 대한 참조를 유지할 계획이었습니다. 나는이 같은 참조를 유지하는 것이 시스템의 어디에서나 문제를 일으키지 않는다고 가정하고 있습니다.

더 심각한 문제는 Runnable이 큐에서 제거되어 시작되었는지 알 수있는 방법이 있어야한다는 것입니다. Runnable 클래스에 플래그를 추가하고 run() 메서드의 시작 부분에 설정하여 처리 할 계획입니다. 플래그의 테스트와 Runnable (백그라운드 thread)의 갱신과 Runnable가 실행 (이벤트 thread)의 실행을 개시하면 (자), 플래그를 설정하는 사이의 레이스 조건을 회피하기 위해서 (때문에) 몇개의 동기가 필요합니다.

누구나 이런 식으로 일한 적이 있습니까? 그렇다면 어떻게 했습니까? 내가 처리해야 할 것을 간과하고 있습니까?

답변

1

그건 좀 심한 버그를 코딩하는 것처럼 보입니다. 저는 피드 veeeeery를 자주 받고 여러 구성 요소에 게시하는 프로그램이 있습니다. 실제로 많은 피해를주지는 않으며 눈에 보이는 부작용이 없습니다.

정말 (당신의 상황을 완전히 이해하지 못할 수도 있습니다.) 더 쉬운 일이 아니고, 필요한 모든 작업이 저장되고 어떤 종류의 "작업 청크"풀을 갖고 싶지 않은 경우 새 Runnable을 한 번 실행하는 작업 스타터. 다음과 같이 진행됩니다.

첫 번째 이벤트에서 "작업 스타터"는 실행 프로그램을 처리기에 게시합니다. 이 실행 파일은 풀에 현재 사용 가능한 모든 작업을 제공하고 처리하도록 요청하고, 결국 "작업 스타터"에게 완료되었음을 알리고 시작자는 다른 실행 파일을 실행하고 풀을 요청하여 새 작업을 요청합니다. 게시 한 실행 파일은 풀에 대한 쿼리를 작성하고 완료된 작업에 대해 더 쉽게보고 할 수 있도록 자신의 작업자 실행 가능 파일의 하위 클래스가 될 수 있습니다. 플래그를 저장하거나 실행 파일을 변경할 필요가 없습니다. 그리고 동시성 문제를 다룰 필요가 없다. (핸들러가 하나 밖에 없다면)

+0

나는 이것을 좋아한다. 나는 사물을 조정하는 복잡성에 대해 우려했습니다. (나는 당신의 첫 문장에 완전히 동의합니다.) 작업 풀과 작업 시작을 소개하면이 문제를 아주 잘 해결할 수 있습니다. 감사! 작업 청크를 풀에 넣는 데는 여전히 작은 동시성 문제가 있지만 표준 제작자/소비자 패턴이이를 수행합니다. 이것을 해결 된 것으로 표시하기 전에 다른 누군가가 다른 개선안을 제안하는지 조금만보고 싶습니다. –