void GoSplash() {
new Thread(new Runnable() {
public void run() {
while (true) {
SystemClock.sleep(600);
//if (PBLODING == 0) { //
handler.sendEmptyMessage(0);
break;
//}
}
}
}).start();
}
private Handler handler = new Handler() {
public void handleMessage(Message msg) {
switch (msg.what) {
case 0: // 로딩화면 닫기
Intent intentSplash = new Intent(mContext, Splash.class);
intentSplash.putExtra("death", 1);
startActivity(intentSplash);
break;
}
}
};
- example two
ThreadSplash mThreadSplash = new ThreadSplash();
mThreadSplash.setDaemon(true);
mThreadSplash.run();
//로딩 화면 체크
class ThreadSplash extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(PBLODING){
try{
Thread.sleep(300);
if(_WVLoding_){
HandlerSplash.sendEmptyMessage(0);
}
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
Handler HandlerSplash = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch(msg.what){
case 0:
//처리
break;
}
}
};
1) Thread 클래스를 상속
2) Runnable 인터페이스를 구현한 클래스를 구현하고 Thread 의 인스턴스를 연결
[Thread]
Thread를 상속할때는 새로운 스레드가 실행할 코드를 run() 메소드에 오버라이드 시킨다
Runnable 객체를 매개변수로 받아 객체를 생성할수 있다.
Thread()
Thread(Runnable)
Thread(Runnable, String threadName)
Thread(ThreadGroup, Runnable, String threadName)
start() :: 메소드는 run() 메소드를 호출한다.
sleep(long milisecs) :: 지정된 초만큼 멈춘다.
sleep(long milisecs, int nanosecs) :: long + int 시간동안 멈춘다.
yield() :: 다른 스레드들에게 실행할 기회를 허용해준다.
getName() :: 스레드 이름 반환
Thread.activeCount() :: 현재 실행중인 스레드 갯수
Thread.enumerate() :: 실행중인 스레드들로 배열을 채운다.
Thread.currentThread() :: 현재 스레드 반환
Thread.dumpStack() :: 현재 메소드와 콘솔 스트림을 호출하는 모든 메소드 출력
Thread 클래스를 상속 받는 방법.(java.lang 에 포함되어 잇음)
class A extends Thread {
public void run() { //Thread를 실행하라고 하면.. 이 메소드 부터 실행이 된다.
}
} //A라는 클래스가 하나의 Thread가 된다.
.
.
.
A ap = new A()
// ap.run(); //하면 단순히 메소드의 실행만 될 뿐이다. 그래서.. 호출하지 않는다.
ap.start(); //하면 새로운 작업 흐름을 만들고 그것을 실행 시키라고 알려 주는것이다.
//start()는 Thread 객체에 포함된 메소드 이다.
[Runnable]
자바에서는 다중상속을 지원하지 않기 때문에 확장 클래스에서 쓰레드로 실행하길 원한다면
Runnable 인터페이스를 구현하면 된다.
Thread의 생성자는 Runnable 을 매개변수로 받기도 하기 때문이다.
이렇게 결합된 스레드가 실행될때는 Runnable 객체의 Run메소드가 실행된다.
Runnable 인터페이스를 상속 받는 방법.
class A implements Runnable {
public void run() { //Runnable 에는 이것 하나의 메소드 밖에 없다.
}
}
A ap = new A();
Thread tt = new Thread(ap); // 바로 실행이 안되므로 Thread에 담아서 실행 시켜야 한다.
tt.start();
[Daemon Thread]
하나이상의 스레드를 가지고 있을때 그중 하나가 종료 되었음을 표현할수 있게 도와 준다.
setDaemon(boolean) 메소드는 스레드가 데몬인지 아닌지를 결정할 수 있게 한다.
이 메소드는 쓰레드 시작전 호출되어야하기 때문에 시작된 스레드는 데몬으로 바뀔수 없다.
데몬 스레드는 JVM 종료에 의해 종료될때 스스로의 스레드를 정리 할 수 없다는것을 주의하자
==========================================================================
프로그래밍을 하다보면 현재 작업 중인 다수의 쓰레드(Thread)들을 종료시켜야 하는 경우가 종종 있습니다.
그런 경우 어떤 방법으로 종료를 하면 좋을까요...?
1. stop()을 쓰지말고 interrupt()를 써라
2. 예외 처리
3. isInterrupted()와 interrupted()
2. 예외 처리
3. isInterrupted()와 interrupted()
일단 Java의 Thread 클래스는 기본적으로 stop() 메소드를 갖고 있습니다.
하지만, !!!
stop() 메소드는 가급적 절대 쓰지 않는 것이 좋습니다.
stop() 메소드는 쓰레드 내에서 중요한 부분이나 크리티컬 섹션(Critical Section)을 수행 중일 때도
그냥 갑작스럽게 종료할 수 있습니다. 상당히 막강하죠. 하지만, 그 덕분에 그만큼 시스템이 불안정해질 수
있습니다. 데이터가 날아가거나 이상한 자료들로 덮어씌워져 버리거나 하는 문제점이 발생할 수 있죠.
그럼 쓰레드를 중간에 중지 시키고 싶을 때는...?
interrupt() 메소드를 활용하는 것이 좋습니다.
interrupt() 메소드는 호출되는 즉시, 해당 Thread가 정지하지 않습니다.
interrupt() 메소드가 호출되어도 현재 Thread는 현재 하고 있는 작업을 묵묵히 수행합니다.
그러다가 sleep(), wait(), join() 메소드 등을 만나면 그 때야 비로소 Thread를 종료하게 됩니다.
즉, 그만큼 Thread의 Critical Section의 안정성을 보장할 수 있다는 말입니다.
Java 라이브러리에서 지원하는 함수들 중에 InterruptedException이 붙어 있는 대표적 메소드는 다음과 같습니다.
wait() 메소드
sleep() 메소드
join() 메소드
sleep() 메소드
join() 메소드
즉, 이 함수들은 interrupt() 명령을 받으면 InterruptedException 예외를 발생하며 예외 처리로 넘어갑니다.
여기서도 각 함수들의 차이가 조금씩 있습니다.
sleep() 메소드나 join() 메소드는 Thread에서 따로 락(Lock)을 해제하지 않고 그냥 쓰는 메소드들이기 때문에,
interrupt() 명령을 받을 때도 락을 소유하고 있습니다. 즉, interrupt() 명령을 받자마자 바로 예외 처리로 넘어갑니다.
하지만, wait() 메소드는 락을 해제하면서 해당 인스턴스(instance)의 wait 셋으로 갑니다.
이 상태에서 interrupt() 명령을 받으면, 락을 다시 획득할 때까지 대기하고 있다가 락을 얻은 뒤 예외 처리로 넘어갑니다.
interrupt() 명령을 받을 때도 락을 소유하고 있습니다. 즉, interrupt() 명령을 받자마자 바로 예외 처리로 넘어갑니다.
하지만, wait() 메소드는 락을 해제하면서 해당 인스턴스(instance)의 wait 셋으로 갑니다.
이 상태에서 interrupt() 명령을 받으면, 락을 다시 획득할 때까지 대기하고 있다가 락을 얻은 뒤 예외 처리로 넘어갑니다.
분명한 차이가 있으니 조심해야 합니다.
그리고 Thread 클래스 안에는 isInterrupted() 메소드와 interrupted() 메소드가 있습니다.
둘다 리턴값은 같습니다.
현재 Thread의 상태가 인터럽트 상태라면 true, 그렇지 않으면 false를 리턴합니다.
하지만, isInterrupted() 메소드의 경우는 단순히 결과만 리턴할 뿐 현재 인터럽트 상태를 바꾸지 않습니다. (보존하고 있습니다.)
interrupted() 메소드의 경우는 결과를 리턴하면서 현재 인터럽트 상태를 false로 바꾸어 버립니다.
하지만, isInterrupted() 메소드의 경우는 단순히 결과만 리턴할 뿐 현재 인터럽트 상태를 바꾸지 않습니다. (보존하고 있습니다.)
interrupted() 메소드의 경우는 결과를 리턴하면서 현재 인터럽트 상태를 false로 바꾸어 버립니다.
따라서, 이 두 메소드를 사용할 때는 조금 주의를 해야 합니다.
댓글 없음:
댓글 쓰기