안드로이드 개발 질문/답변
(글 수 45,052)
surfaceView 를 이용하여 간단한 게임을 테스트 삼아 만들고 잇는데.. 플레이 중에
home 버튼을 누르다음 ...다시 들어가면 에러가 뜨는데.. 로그캣에 보니..thread already started ..라고 나오더군요..
그래서 여러가지 방법을 사용하여 해 보앗는데.. 잘 되지 않아서.. surfaceDestroyed() 에서.. thread = null을 해주었습니다.
그리고 다시 surfaceCreated() 에서는
if( thread == null ){
thread = new Thread(......)
thread.start();
}
이렇게 했는데.. 별 이상이 없는 것 같습니다. 그런데.. 이렇게 해도 되는건지 잘 몰라서요..
자바 API 를 보아도 thread 를 멈추는 방법이 없는 것 같아서요..stop() 등등 은 전부다 추천하지 않는 메써드
라고 그래서요.. 혹시 thread = null 을 해주면 나중에 어떤 문제점을 야기 할 수 있는지요.?
2010.04.30 16:49:26
자바에서는 thread를 억지로 죽일수는 있겠지만
자원회수가 잘되지 않는 문제가 생겨 권장하지 않는 방법입니다.(예전버젼에서는.. 요즘에는 모르겠습니다)
그래서, thread를 만들때는 db의 connection pool을 만들듯 미리 사용할 thread pool을 생성해 필요할때 사용하고 사용이 끝나면
반납을 하는 그런방식을 사용하는것이 나중에 문제가 안생깁니다.
이건 순수 자바Application의 경우입니다... 모바일의 경우는 경험이 적으니 참고로 하세요.
자원회수가 잘되지 않는 문제가 생겨 권장하지 않는 방법입니다.(예전버젼에서는.. 요즘에는 모르겠습니다)
그래서, thread를 만들때는 db의 connection pool을 만들듯 미리 사용할 thread pool을 생성해 필요할때 사용하고 사용이 끝나면
반납을 하는 그런방식을 사용하는것이 나중에 문제가 안생깁니다.
이건 순수 자바Application의 경우입니다... 모바일의 경우는 경험이 적으니 참고로 하세요.
2010.04.30 16:59:00
if( thread == null ){
thread = new Thread(......)
thread.start();
}
thread = new Thread(......)
thread.start();
}
를 잘 살펴보니 만약 스레드가 살아있다면 새로 만들고 스타트 시키지 말아라..의 의미가 되는군요....따라서로그캣에 .thread already started ..를 피할 수 있었던거 같은데요..
java thread 에서 stop에 대한 이야기가 나와 있습니다.
어제부터 Handler , message queue , message , thread , process 이렇게 찾아서 보고 있는데 볼때마다 헷갈리는군요 ㅠㅠ
2010.04.30 23:26:16
전 다음 방법을 쓰기도 합니다.
쓰레드 내에 루프가 있으면 해당 루프에서 플래그를 체크하여 수행을 계속 진행하도록 합니다.
쓰레드를 끝내고 싶을 때는 플래그를 조작합니다. 그러면 쓰레드는 작업을 마치고 종료합니다.
진행/종료 상태가 필요하면 쓰레드 실행하는 쪽의 핸들러 등을 미리 받았다가 메시지를 날려주는 방법도 있습니다.
class ThreadRunner implement Runnable {
private boolean mCanceled;
public void cancel() {
mCanceled = true;
}
public void run() {
while ( ... ) {
if (mCanceled) break;
...
}
}
}
쓰레드 내에 루프가 있으면 해당 루프에서 플래그를 체크하여 수행을 계속 진행하도록 합니다.
쓰레드를 끝내고 싶을 때는 플래그를 조작합니다. 그러면 쓰레드는 작업을 마치고 종료합니다.
진행/종료 상태가 필요하면 쓰레드 실행하는 쪽의 핸들러 등을 미리 받았다가 메시지를 날려주는 방법도 있습니다.
class ThreadRunner implement Runnable {
private boolean mCanceled;
public void cancel() {
mCanceled = true;
}
public void run() {
while ( ... ) {
if (mCanceled) break;
...
}
}
}
그 스레드는 계속 돌고 있구요, 이제 더 이상 그 스레드를 제어할 수 없게 되므로 그리 좋은 방법은 아닌 것 같습니다.
스레드를 올바르게 죽이려면 해당 스레드에 인터럽트를 거는게 제일 좋습니다.
이때 해당 스레드는 인터럽트를 받으면 곱게 죽도록 처리가 되어있어야겠지요.