AsyncTask 스레드는 절대 죽지 않습니다.


112

AsyncTask사용자가 버튼을 누르는 것에 대한 응답으로 데이터를 가져 오기 위해 s를 사용 하고 있습니다. 이것은 잘 작동하고 데이터를 가져 오는 동안 인터페이스의 응답 성을 유지하지만 이클립스 디버거에서 무슨 일이 일어나고 있는지 확인할 때마다 새 파일 AsyncTask이 생성 될 때마다 (한 번만 사용할 수 있기 때문에 자주 발생 함) ), 새 스레드가 생성되었지만 종료되지 않았습니다.

그 결과 많은 수의 AsyncTask스레드가 그대로 있습니다. 이것이 실제로 문제인지 아닌지는 확실하지 않지만 추가 스레드를 제거하고 싶습니다.

이 스레드를 어떻게 죽일 수 있습니까?


"종료되지 않음"이란 무엇을 의미합니까? 작업이 doInbackground 메서드를 종료하지 않거나 할당 추적기에서 asynctask 개체 만 표시됩니까?
Francesco Laurita

7
doInBackground방법은 완료되지만 스레드 디버그 창에 표시하고 있습니다. 예 : Thread [<23> AsyncTask #4](Running)
Computerish

답변:


202

AsyncTask로 생성 된 스레드 풀을 관리합니다 ThreadPoolExecutor. 5 ~ 128 개의 스레드가 있습니다. 5 개 이상의 스레드가있는 경우 추가 스레드는 제거되기 전에 최대 10 초 동안 붙어 있습니다. (참고 :이 수치는 현재 볼 수있는 오픈 소스 코드에 대한 것이며 Android 릴리스에 따라 다릅니다).

AsyncTask실은 그대로 두세요 .


설명해 주셔서 감사합니다! 내가 잘못한 것이 없다는 것을 알게되어 기쁩니다. 호기심 때문에 왜 그렇게 디자인 되었나요? 모든 메서드가 반환 된 후 스레드를 종료하지 않는 이유는 무엇입니까?
Computerish

7
아마도 나중에 요청에서 스레드를 분기하는 시간을 절약하기 위해.
CommonsWare 2010-06-20

@CommonsWare 나는 AsyncTask를 실행하여 일부 작업을 수행하고 위젯 버튼을 눌렀을 때 서비스가 시작되고 작업이 완료되면 서비스를 즉시 중지해야하지만 때로는 AsyncTask가 죽지 않습니다. 중지하는 방법을 알려주세요
Hunt

1
@SreekanthKarumanaghat : AsyncTask그렇게 오래 걸리는 무언가를 위해를 사용하는 것은 일반적으로 나쁜 생각입니다. 그러나 아니요, 추가 스레드가 사라지는 것에 대한 내 의견은 사용하지 않을 때입니다. 따라서 6 개 작업 중 하나가 종료되면 해당 스레드는 풀에 10 초 동안 남아 있으며 그 후 해당 스레드가 종료됩니다.
CommonsWare

1
@SreekanthKarumanaghat : "제 질문은 병렬로 AsyncTasks 20 개를 실행하는 데 제한이 있는지 여부입니다." - AsyncTask오늘 을 많이 활용 하는 것은 좋은 계획이 아닙니다. 10 초 이상 실행할 수있는 20 개 이상을 갖는 것은 코드 검토에 실패해야하는 일종의 것입니다. 20 개의 작업을 빠르게 연속적으로 생성하면 한 번에 몇 개만 실행되고 나머지는 나중에 실행될 수 있도록 대기열에 추가됩니다. 한 번에 실행할 수는 CPU의 코어 수에 따라 다릅니다. AFAIK, 현재 알고리즘은 2N + 1 병렬 스레드이며 여기서 N은 코어 수입니다.
CommonsWare

24

CommonsWare의 응답에 추가하여 :

현재 저는 Android 2.2를 사용하고 있으며 내 애플리케이션은 한 번에 하나 이상의 AsyncTask를 사용하지 않지만 x 분마다 새 작업을 만듭니다. 처음에는 새 AsyncTask 스레드가 나타나기 시작하지만 (새 AsyncTask에 대한 새 스레드) 5 개 스레드 (CommonsWare에서 언급했듯이) 후에는 디버그 창에 계속 표시되고 새 AsyncTask 스레드가 필요할 때 다시 사용됩니다. 디버거가 연결이 끊어 질 때까지 그대로 유지됩니다.


2
예, 확인했습니다. AsyncTask가 5 개만 표시됩니다.
Seraphim의

3

여기에도 같은 증상이 있습니다. 제 경우에는 활동을 죽인 후 스레드가 매달려 있었고 앱이 완전히 닫히기를 바랐습니다. 단일 스레드 실행기를 사용하여 부분적으로 해결 된 문제 :

    myActiveTask.executeOnExecutor(Executors.newSingleThreadExecutor());

이로 인해 작업이 완료된 후 실이 사라졌습니다.


이 답변은 AsyncTask가 실행 된 후 사라지도록 만들었습니다. 아마도 "Google 방식의 작업"은 아니지만 작업이 완료됩니다. 감사합니다.
Henrique de Sousa 2014

이것은 단일 스레드에서 Asynctasks를 실행하는 것과 관련된 내 특정 문제를 해결했습니다.
법률 히메네스

0

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);

execute () 메서드 Runnable를 사용 하여 작업을 게시하십시오 .

void execute (Runnable command)

미래에 주어진 작업을 실행합니다. 작업은 새 스레드 또는 기존 풀링 된 스레드에서 실행될 수 있습니다.

두 번째 쿼리와 관련하여 :

이 스레드를 어떻게 죽일 수 있습니까?

을 (를) 사용한 모든 작업이 끝나면 ThreadPoolExecutor아래 게시물에 인용 된대로 제대로 종료하십시오.

Java ExecutorService를 올바르게 종료하는 방법

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.