마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

안드로이드 스레드 종료 질문

0 추천
안녕하세요 안드로이드 스레드 종료 관련하여 질문 드리고 싶습니다,

 

스레드를 강제종료 (메인이 끝나기전에 종료) 를 하려고 했는데 혹자의 말로는

스레드를 강제종료해도 잔재? 가 남아있기 때문에 제대로 종료가 안된다고 하더라구요.

저의 경우는 interrupt() 와 isInturrupted를 활용하여 종료를 해보려고 하는데 잘 되질 않더라구요,.

이것의 해결방안을 묻고 싶습니다.

그리고 또 궁금한 것이 있는데, 저는 그 스레드가 돌아가는 중에 특정한 경우 (즉 i를 0부터 15까지 돌리는 반복문에서 i가 14일때)에 Intent를 해서 다른 액티비티를 호출하고, finsh() 메소드를 호출하였습니다 .그러면, 해당 액티비티가 finish()되므로 스레드도 다 종료되어야 하는 것 아닌지 궁금합니다.

제가 잘못 알고 있는 지식이 있다면 말씀해주세요!
SuperPro (860 포인트) 님이 2014년 11월 4일 질문

2개의 답변

0 추천
쓰레드는 별도의 프로세스라고 보시면 됩니다.

액티비티에서 사용한 변수같은 개념으로 보시면 안됩니다.

단순하게 직접 테스트 해보시면 알 수 있을 듯 싶네요

액티비티의 onCreate에서 Thread 하나 만들어서 반복문 15까지 돌리면서 sleep(1000) 하고 로그찍게  만들고

i==2가 되면 activity finish() 시켜보세요

쓰레드는 계속 로그를 찍을 겁니다.

 

쓰레드를 종료 시키는 방법은 말씀하신 대로 다음과 같은 방법도 있고

while(thread.isInterrupted()) {

    thread.intterupt()

}

하지만 가장 많이 쓰는 방법은 다음과 같이

쓰레드 flag를 두어서 종료시키고 싶은 시점에 flag를 false로 바꿔주는 겁니다.

boolean run = true;

run () {

     while(run) {

         // do something...

     }

}

run = false;

잔재가 남는다고 하셨는데 어떤 잔재(?)를 말씀하시는건지..

그닥 신경쓰지 않아도 될 듯 합니다. 
Gradler (109,780 포인트) 님이 2014년 11월 5일 답변
우선 답변 정말 감사드립니다.
제가 표현을 좀 애매하게 했네요 ㅠㅠ
그 잔재라는게 제가 run함수에서 for문을 돌게 했는데 그중에 i 가 14일때 멈추고 Intent로 다른 액티비티로 넘어가게 했습니다. 근데 이 액티비티도 마찬가지로 쓰레드를 사용하는 액티비티입니다. 그래서 이게 인텐트가 한번만 되거나 되지말아야되는 상황에 갑자기 i가 14일때가 되버리면 바로 인텐트가 되어버리는 문제가 있었습니다.
0 추천
쓰레드 개념을 잘못잡고계신거같은데,

쓰레드는 다른 cpu라고 생각하시면 됩니다.

즉 한 액티비티에서 UI작업을 하고있고, 용량이 큰 작업을 돌릴려고할때 다른 cpu를 돌리겠다는 의미로 쓰레드를 실행하는겁니다.

그러면 한cpu는 UI작업을 할수있고, 다른 cpu는 대용량작업을 따로 할수있겠죠.

 

근데 다른cpu에서 i를 1부터 14까지 카운트한뒤에 intent로 다른 액티비티로 넘겼다는건 전혀 다른의미죠.

메인쓰레드에서 intent를하던 다른쓰레드에서 intent를하던 똑같은 작업입니다.

다만 다른 cpu(다른 프로세스)를 사용해서 계산을 하겠다는얘깁니다.

 

즉 while문으로 i++무한루프를 하나의 쓰레드로 만들고

현제 액티비티를 finish로 종료시킨다.

하면 현재 액티비티를 관리하고있는 메인쓰레드는 종료되겠죠.

하지만 다른 쓰레드는 i++ 무한루프를 돌고있기때문에 앱이 꺼져도 계속 돌아갑니다.

 

즉 무슨말이냐,

님이 쓰레드를 실행시키는건 다른 프로세스를 실행시켜달라고 요청을 하는것이고,

새 프로세스가 생성되면 작업 할당은 할 수 있어도 마음대로 종료는 못한다 이말입니다.

즉, 새 쓰래드에 작업 할당을 해주고난뒤에, 로직이 다 끝나면 알아서 쓰레드를 종료하던지,

님이 interrupt로 종료해달라고 요청하면 프로세스가 종료할때까지 기다리는수밖에 없습니다.

 

그렇다면 쓰레드를 종료했다가 다시 어떻게 재시작시키는가 에대한 궁금증이 있을텐데,

쓰래드는 항상 새로 실행시키는게 옳습니다.

즉, 님이 앱을 실행하면 쓰레드 하나가 돌면서 님 앱을 실행시킵니다.

그리고 finish를 하면 앱이 종료가 되겠죠.

그다음 다시 앱을 실행시키면 전에 쓰던 쓰레드를 종료시키고 다시 실행하는게아니라,

새로운 쓰레드를 다시 실행시켜서 실행하는겁니다.

 

간단히말해서,  쓰레드는 로직이 끝나면 알아서 종료된다.

도중에 강제종료하고싶으면 flag를 두거나 interupt를 해서 쓰레드 종료 요청을 하고 새 쓰레드를 만들어라.

 

참고삼아 다른프로세스를 다른cpu라고 표기했는데, 예를든것이고 다중코어면 다른 cpu가, 싱글코어면 한cpu에서 다중 프로세스를 생성해 스케쥴링기법 등 OS가 알아서 관리합니다.
기초개발자 (24,060 포인트) 님이 2014년 11월 5일 답변
답변 대단히 감사드립니다. 제가 개념을 잘못생각하고 있었군요.
...