프로그래밍/JAVA 자바
스레드(3) Timer 클래스 / wait
Heidong
2021. 9. 7. 00:01
반응형
package threadEx2;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class Ex001_Timer {
public static void main(String[] args) {
new MyTimer();
}
}
class MyTimer {
public MyTimer() {
// TimerTask : 타이머에 의해 1회 또는 반복 실행하도록 태스크되는 스케줄
TimerTask task = new TimerTask() {
@Override
public void run() {
printTimes();
}
};
// Timer : 스케줄
// 단점 : 시간이 지연 될 수 있다.(0.001 ~ 0.002 초)
Timer t = new Timer();
// t.schedule(task, 1000); // 1초후 한번 실행
// t.schedule(task, 2000, 1000); // 2초후 1초 마다 무한 반복
t.schedule(task, new Date(System.currentTimeMillis()), 1000); // 바로 실행하며 1초마다 무한 반복
// t.cancel(); // 타이머 종료
}
private void printTimes() {
Calendar cal = Calendar.getInstance();
String s = String.format("%tF %tT", cal, cal);
System.out.println(s);
}
}
- TimerTask = 타이머에 의해서 1회 또는 반복 실행 하도록 테스크 되는 스케줄
- Timer = 스케쥴
- .schedule(task, , )를 사용해서 간격을 조절 할 수 있다.
(t는 Timer 객체 생성한거임)
t.schedule(task, 1000); // 1초후 한번 실행
t.schedule(task, 2000, 1000); // 2초후 1초 마다 무한 반복
t.schedule(task, new Date(System.currentTimeMillis()), 1000); // 바로 실행하며 1초마다 무한 반복
package threadEx2;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
public class Ex002_Timer {
public static void main(String[] args) {
MyScheduler t = new MyScheduler();
t.start();
}
}
class MyScheduler extends Thread {
private long num = 0;
public MyScheduler() {
TimerTask task = new TimerTask() {
@Override
public void run() {
num = 0;
}
};
/*
Timer t = new Timer();
Calendar cal = Calendar.getInstance();
t.schedule(task, cal.getTime(), 10000); // 바로 실행하며, 10초 마다 반복 실행
*/
// 다음날 0시 0분 0초에 시작하여 하루에 한번씩 반복
Timer t = new Timer();
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, 1);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
t.schedule( task, cal.getTime(), 1000*60*60*24 );
}
public void run() {
while(true) {
try {
System.out.println("num : " + (++num));
sleep(1000);
} catch (Exception e) {
}
}
}
}
- num을 1초마다 증가시킴
- 다음날 0시 0분 0초에 시작하여 하루에 한번씩 반복
Wait
package threadEx2;
public class Ex005_wait {
public static void main(String[] args) {
MyBank3 atm = new MyBank3();
Thread t1 = new Thread(atm, "t1");
Thread t2 = new Thread(atm, "t2");
t1.start();
t2.start();
}
}
class MyBank3 implements Runnable {
private long money = 10000;
public void run() {
synchronized (this) {
for(int i = 0; i < 10; i++) {
if(getMoney() <= 0) {
// wait()에 의해 대기하고 있는 모든 스레드를 깨운다.
this.notifyAll();
break;
}
drawMoney(1000);
if(getMoney()>=2000 && getMoney() % 2000 == 0) {
try {
// wait()를 만나면 해당 쓰레드는 해당 객체의 모니터링 락에 대한 권한을 가지고 있으면
// 모니터링 락의 권한을 놓고 대기한다.
// synchronized 블록에서만 사용
this.wait();
} catch (Exception e) {
}
} else {
// wait()에 의해 대기하고 있는 해당 스레드를 깨운다.
// 아래 notify()를 주석 처리하면 무한 대기(deadlook) 상태가 된다.
this.notify();
}
}
}
}
public long getMoney() {
return money;
}
public void drawMoney(long m) {
System.out.print(Thread.currentThread().getName()+", "); // 현재 스레드명 출력
if(getMoney() >= m) {
money -= m;
System.out.printf("잔액 : %,d원\n", getMoney());
} else {
System.out.println("잔액이 부족 합니다.");
}
}
}
wait과 notify는 동기화된 스레드에서만 사용이 가능하다.
- 간단하게 wait을 만나면 대기함
- notify하면 깨움
- notifyAll하면 모든 잠들어 있는 스레드를 깨움
반응형