Android 의 스 레 드 와 스 레 드 풀 분석
내용 이 너무 많 기 때문에 상하 두 부분 으로 나 눌 것 입 니 다.첫 번 째 부분 은 주로 안 드 로 이 드 의 스 레 드 와 안 드 로 이 드 에서 자주 사용 하 는 스 레 드 풀 에 대해 이야기 할 것 입 니 다.두 번 째 부분 에 서 는 AsyncTask 의 사용 과 작업 원 리 를 함께 알 아 보 겠 습 니 다.
HandlerThread
HandlerThread 는 Thread 의 하위 클래스 로 Handler 를 사용 할 수 있 는 Thread 로 실현 이 간단 합 니 다.우 리 는 그것 의 소스 코드 를 보 자.
package android.os;
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
if (!isAlive()) {
return null;
}
// If the thread has been started, wait until the looper has been created.
synchronized (this) {
while (isAlive() && mLooper == null) {
try {
wait();
} catch (InterruptedException e) {
}
}
}
return mLooper;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
여러분 에 게 똑똑히 보 여 드 리 기 위해 서,우리 의 원본 코드 의 일부 영어 주석 이 제거 되 었 는데,지금 은 매우 뚜렷 해 졌 다.전체 유형 에서 구조 방법 과 대외 적 으로 몇 가지 Public 방법 을 제공 하 는 것 을 제외 하고 run()만 남 았 다.그것 의 실현 을 보면 일반적인 Thread 실현 과 별 차이 가 없다.모두 run()방법 에서 시간 소모 작업 을 수행 합 니 다.그러나 HandlerThread 내부 에 메시지 대기 열 을 만 들 었 고 run()방법 은 무한 순환 방법 입 니 다.HandlerThread 가 필요 하지 않 을 때 quitSafely()나 quit()방법 으로 이 스 레 드 를 끝 낼 수 있 습 니 다.이것 은 비교적 편리 하 다.IntentService
IntentService 는 특수 한 Service 로 Service 의 하위 클래스 이 며 추상 적 인 클래스 이기 때문에 하위 클래스 를 만들어 야 Intent Service 를 사용 할 수 있 습 니 다.Intent Service 는 배경 작업 을 수행 하 는 데 사용 할 수 있 습 니 다.작업 이 완료 되면 스스로 끝 납 니 다.수 동 으로 끝 낼 필요 가 없습니다.여기 서 주의해 야 할 문 제 는 Intentservice 에 스 레 드 가 내장 되 어 있 지만 Service 에 속 하기 때문에 우선 순위 가 스 레 드 보다 훨씬 높 기 때문에 시스템 에 의 해 쉽게 죽 이지 않 습 니 다.우선 순위 가 높 은 임 무 를 수행 하 는 것 이 좋 습 니 다.원본 코드 보기:
package android.app;
import android.annotation.WorkerThread;
import android.annotation.Nullable;
import android.content.Intent;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
이곳 은 간단 하 다.이런 방법 들 은 서 비 스 를 자주 사용 하 는 친구 들 에 게 익숙 하 다.여러분,onCreate()방법 을 보 세 요.맞습니다.인 텐 트 서 비 스 는 Handler Thread 와 Handler 를 봉 인 했 습 니 다.IntentService 가 onCreate()를 시작 하면 방법 이 호출 되 고 HandlerThread 와 ServiceHandler 를 만 듭 니 다.한편,onStart Command()방법 은 onStart()방법 을 호출 했다.onStart()방법 을 통 해 알 수 있 듯 이 IntentService 는 ServiceHandler 를 통 해 메 시 지 를 보 내 는 것 일 뿐 이 메 시 지 는 Handler Thread 에서 처 리 될 것 이다.
이 onStart()방법 을 보 세 요.intent 를 메시지 로 onHandleIntent 에 전달 합 니 다.이 intent 는 보통 우리 가 전달 하 는 데이터 입 니 다.온 핸드 인 텐트 는 이 인 텐트 를 통 해 구체 적 인 백 스테이지 임 무 를 구별 하 는 것 이다.
자,AsyncTask 의 사용 과 작업 원리.우 리 는 다음 장 에서 말 할 것 이다.다음은 스 레 드 탱크 를 봅 시다.
모두 가 이런 상황 을 만난 적 이 있 는 지 모르겠다.우 리 는 프로젝트 를 쓰 고 있 습 니 다.시간 이 걸 릴 때 어떻게 해 야 합 니까?new Thread().start 가 아 닙 니까?그러면 전체 프로젝트 에 new 몇 개의 Thread 가 필요 합 니까?이런 것 은 분명히 성능 을 낭비 하 는 것 이다.스 레 드 도 좋 은 자원 이 니까.그렇다면 스 레 드 를 재 활용 할 수 있 는 방법 은 없 을 까?정 답 은 스 레 드 탱크 다.
스 레 드 탱크 의 장점
1.스 레 드 탱크 의 스 레 드 를 다시 사용 하여 스 레 드 의 생 성 과 소각 으로 인 한 성능 비용 을 피한다.
2.스 레 드 탱크 의 스 레 드 병발 수 를 효과적으로 제어 하고 대량의 스 레 드 간 에 서로 자원 을 선점 하기 때문에 발생 하 는 차단 현상 을 피 할 수 있 습 니 다.
3.라인 에 대해 간단 한 관 리 를 할 수 있 고 정시 집행 과 지정 한 간격 순환 집행 등 기능 을 제공 할 수 있다.
ThreadPoolExecutor
Android 의 스 레 드 탱크 개념 은 자바 에서 Executor,Executor 는 빈 인터페이스 이 고 진정한 스 레 드 탱크 는 Thread PoolExecutor 를 실현 합 니 다.
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
ThreadPoolExcutor 매개 변수의 의 미 를 간단하게 소개 합 니 다.core PoolSize:스 레 드 탱크 의 핵심 스 레 드 수 입 니 다.기본 적 인 상황 에서 핵심 스 레 드 는 온라인 스 레 드 탱크 에서 계속 살아 남 습 니 다.설령 그들 이 방치 상태 에 있 더 라 도.Thread PoolExecutor 의 allow CoreThreadTimeOut 속성 을 true 로 설정 하면 유 휴 된 핵심 스 레 드 가 새로운 작업 을 기다 리 고 있 을 때 keepAliveTime 이 설정 한 시간 을 초과 하면 핵심 스 레 드 가 회 수 됩 니 다.
maximumPoolSize:최대 스 레 드 탱크 가 수용 할 수 있 는 최대 스 레 드 수 를 설정 합 니 다.스 레 드 탱크 의 스 레 드 가 이 수 에 도달 하면 새 작업 이 막 힐 것 입 니 다.
keepAliveTime:비 핵심 스 레 드 수 방치 시간.
유닛:keepAliveTime 매개 변수의 시간 단 위 를 지정 합 니 다.
work Queue:스 레 드 탱크 의 작업 대기 열 입 니 다.
threadFactory:스 레 드 공장,스 레 드 탱크 에 새로운 스 레 드 를 만 드 는 기능 을 제공 합 니 다.
스 레 드 탱크 의 분류
Android 에서 흔히 볼 수 있 는 스 레 드 풀 은 Fixed ThreadPool,Cached ThreadPool,Scheduled ThreadPool,Single ThreadExecutor 네 가지 가 있 습 니 다.
FixedThreadPool
Fixed ThreadPool 스 레 드 풀 은 Executors 의 new Fixed ThreadPool 방법 으로 만 듭 니 다.그것 의 특징 은 이 스 레 드 탱크 의 스 레 드 수량 이 고정 되 어 있다 는 것 이다.스 레 드 가 유 휴 상태 에 있 더 라 도 스 레 드 탱크 가 닫 히 지 않 는 한 회수 되 지 않 습 니 다.모든 스 레 드 가 활성 상태 에 있 을 때 새 작업 은 대기 열 에서 스 레 드 를 기다 리 고 있 습 니 다.Fixed ThreadPool 은 핵심 스 레 드 만 있 고 비 핵심 스 레 드 는 없습니다.
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
CachedThreadPoolCached ThreadPool 스 레 드 풀 은 Executors 의 new Cached ThreadPool 을 통 해 만 들 어 졌 습 니 다.이것 은 스 레 드 수가 고정 되 지 않 은 스 레 드 탱크 입 니 다.핵심 스 레 드 가 없고 비 핵심 스 레 드 만 있 습 니 다.스 레 드 탱크 의 스 레 드 가 모두 활성 상태 에 있 으 면 새로운 스 레 드 를 만들어 새로운 작업 을 처리 합 니 다.그렇지 않 으 면 유 휴 스 레 드 를 이용 하여 새로운 임 무 를 처리 할 것 이다.스 레 드 탱크 의 스 레 드 는 모두 시간 초과 메커니즘 이 있 는데 이 시간 초과 메커니즘 은 시간 이 60s 이 고 이 시간 을 초과 하면 유 휴 스 레 드 는 회수 된다.이런 스 레 드 탱크 는 대량의 시간 을 소모 하 는 임 무 를 처리 하기에 적합 하 다.Cached ThreadPool 의 미 션 대기 열 은 기본적으로 비어 있 습 니 다.
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
ScheduledThreadPoolScheduled ThreadPool 스 레 드 풀 은 Executors 의 new Scheduled ThreadPool 을 통 해 만 들 어 졌 습 니 다.핵심 스 레 드 는 고정 되 어 있 지만 비 핵심 스 레 드 수 는 고정 되 어 있 지 않 으 며 비 핵심 스 레 드 가 비어 있 으 면 바로 회수 되 었 습 니 다.이런 라인 은 정시 임 무 를 수행 하고 고정 주 기 를 가 진 중복 임 무 를 수행 하기에 적합 하 다.
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory);
}
SingleThreadExecutorSingleThreadExecutor 스 레 드 풀 은 Executors 의 new SingleThreadExecutor 방법 을 통 해 만 들 어 졌 습 니 다.이러한 스 레 드 풀 에는 하나의 핵심 스 레 드 만 있 고 비 핵심 스 레 드 도 없습니다.이 는 모든 작업 이 같은 스 레 드 에서 순서대로 실 행 될 수 있 도록 확보 합 니 다.그러면 스 레 드 동기 화 문 제 를 고려 할 필요 가 없습니다.
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
이상 은 안 드 로 이 드 의 스 레 드 와 스 레 드 탱크 의 상세 한 내용 을 분석 하 는 것 입 니 다.안 드 로 이 드 의 스 레 드 와 스 레 드 탱크 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.