장시간 실행되는 작업 이나 네트워크를 사용하는 논리 와 같은 비동기식 으로 실행해야 할 필요가 있거나 어떤 이유로 든 새 스레드를 시작 하고 실행하는 것이 좋습니다. 만들기 처리기를 하고 그것을 실행하는 것은 잘 작동합니다. 차이점이 뭐야? 언제 사용해야합니까? 를 사용하는 것이 아닌 장점은 무엇입니까 ?Handler
Thread
추신. -이 질문을 위해 무시합시다 AsyncTask
. – Handler().postDelayed
유스 케이스는 나에게 분명합니다.이 질문을 위해 즉시 시작해야 할 작업이 필요하다고 가정 해 봅시다.
답변
만약 당신이하고있는 것이 “무거운”이라면 당신은 스레드에서 그것을해야합니다. 자체 스레드에서 명시 적으로 시작하지 않으면 기본 (UI) 스레드에서 실행되어 사용자가 인터페이스를 느리게 응답하거나 느리게 보일 수 있습니다.
흥미롭게도 스레드를 사용할 때 시작하는 작업 스레드와 기본 스레드 간의 통신 수단으로 핸들러를 사용하는 것이 유용합니다.
일반적인 스레드 / 핸들러 상호 작용은 다음과 같습니다.
Handler h = new Handler(){
@Override
public void handleMessage(Message msg){
if(msg.what == 0){
updateUI();
}else{
showErrorDialog();
}
}
};
Thread t = new Thread() {
@Override
public void run(){
doSomeWork();
if(succeed){
//we can't update the UI from here so we'll signal our handler and it will do it for us.
h.sendEmptyMessage(0);
}else{
h.sendEmptyMessage(1);
}
}
};
그러나 일반적으로 집에 가져 가려면 오래 실행되거나 매우 집중적 인 작업 (예 : 네트워크, 파일 IO, 무거운 산술 등)을 할 때마다 스레드를 사용해야합니다.
답변
핸들러와 스레드는 실제로 두 가지입니다.
장기 실행 작업을 실행하려면 스레드를 작성해야합니다.
핸들러는 2 개의 스레드간에 통신하기에 매우 편리한 객체입니다 (예 : 백그라운드 스레드는 UI를 업데이트해야합니다. 핸들러를 사용하여 백그라운드 스레드에서 UI 스레드로 일부 Runnable을 게시 할 수 있습니다).
따라서 처리기 또는 스레드 중에서 선택할 수 없습니다. 스레드를 사용하여 무거운 작업을 수행하십시오! (백그라운드 스레드가 다른 스레드에서 일부 작업을 트리거하는 경우 핸들러를 사용할 수 있습니다. 대부분의 경우 UI 스레드)
답변
Handler
그리고 Thread
다른 두 가지가 있지만, 그들은 서로 모순되지 않는다. a Handler
와 a Thread
를 동시에 가질 수 있으며 실제로 각각 Handler
에서 실행 중이어야합니다 Thread
.
자세한 내용은 이 기사를 참조하십시오 .
답변
Handler
같은에서 실행 Thread
하는 Thread
다른 스레드에서 실행됩니다.
동일한 스레드 에서 일반적으로 GUI 요소 또는 이와 유사한 것을 실행해야하는 경우 핸들러를 사용하십시오 .
메인 스레드가 다른 작업을 자유롭게 할 수 있도록하려면 스레드를 사용하십시오 . 시간이 많이 걸리는 모든 작업에 사용하십시오.
답변
핸들러는 백그라운드와 UI 스레드 사이의 가장 좋은 통신 방법입니다. 일반적으로 처리기는 스레드의 메시지 큐와 연결되며 메시지를 보내고 메시지에 실행할 수 있습니다.
사용하다:
스레드 : UI 스레드보다 saperate (Background) 스레드에서 작업을 수행합니다. (UI 스레드 차단을 해제하는 데 도움이 됨)
처리기 UI와 백그라운드 스레드 간의 통신에 사용됩니다.
이 기사를보십시오
답변
새 스레드에서 사용자 인터페이스를 업데이트해야하는 경우 사용자 인터페이스 스레드와 동기화해야합니다.
이를 위해 android.os.Handler 클래스 또는 AsyncTasks 클래스를 사용할 수 있습니다.
핸들러 클래스는 사용자 인터페이스를 업데이트 할 수 있습니다. 핸들러는 Message 또는 Runnable 클래스의 인스턴스를 수신하기위한 메소드를 제공합니다.
스레드는 sendMessage (Message msg) 메소드 또는 sendEmptyMessage () 메소드를 통해 메시지를 게시 할 수 있습니다.
… 스레드 등에 대한 자세한 정보는 여기 (다양한 스레딩 및 동기화 메커니즘에 대한 turorials 포함 및 사용시기)
답변
스레드가 아닌 처리기를 사용하는 이점 / 이유는 무엇입니까?
처리기 보내고 프로세스 메시지 수와 Runnable
스레드의와 관련된 객체 MessageQueue
. 각 Handler
인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연관됩니다.
새를 만들면 Handler
스레드를 만드는 스레드의 스레드 / 메시지 큐에 바인딩됩니다. 이때부터 메시지와 실행 파일을 해당 메시지 큐로 전달하고 메시지 큐에서 나올 때 실행합니다. .
핸들러에는 두 가지 주요 용도가 있습니다.
- 메시지 및 Runnables 가 나중에 특정 시점에 실행되도록 예약하려면
- 자신과 다른 스레드에서 수행 할 작업 을 큐에 넣습니다 .
자바 스레드를 사용하는 경우 메인 스레드와 동기화, 스레드 취소 등 무언가를 스스로 처리해야합니다.
당신이 사용하지 않는 한이 단일 스레드는 스레드 풀을 만들지 않습니다 ThreadPoolExecutor
또는 ExecutorService
API를.
(Blackbelt 답변에 대한 귀하의 의견 에서이 쿼리를 가져 왔습니다)
왜 집행자를 사용하지 않습니까? 처리기를 사용하여 그렇게하고 싶더라도 어떻게해야합니까?
참조 : 스레드 성능 기사
고도의 병렬 분산 작업으로 줄일 수있는 특정 유형의 작업이 있습니다. 작품의 엄청난 양이 (가) 작성하는 패킷, AsyncTask
그리고 HandlerThread
적절한 클래스하지 않습니다. 단일 스레드 특성은 AsyncTask
모든 스레드 풀 작업을 선형 시스템으로 전환합니다. HandlerThread
반면에 클래스를 사용하려면 프로그래머가 스레드 그룹 간의로드 밸런싱을 수동으로 관리해야합니다.
ThreadPoolExecutor 는이 과정을보다 쉽게 해주는 도우미 클래스입니다. 이 클래스는 스레드 그룹 작성을 관리하고 우선 순위를 설정하며 스레드간에 작업이 분배되는 방식을 관리합니다. 워크로드가 증가하거나 감소함에 따라 클래스는 더 많은 스레드를 스핀 업 또는 파괴하여 워크로드에 맞 춥니 다.
BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size
ThreadPoolExecutor executor = new ThreadPoolExecutor(
Runtime.getRuntime().availableProcessors(), // Initial pool size
Runtime.getRuntime().availableProcessors(), // Max pool size
1, // KEEP_ALIVE_TIME
TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT
workQueue);
자세한 내용 은 create-threadpool에 대한 이 개발자 안내서 를 참조하십시오.
Handler
여러 개의 Runnable 인스턴스를 실행하는 방법에 대해서는이 게시물을 살펴보십시오 . 이 경우 모든 Runnable
작업이 단일 스레드에서 실행됩니다.