Thread in Java
자바에서 Thread를 구현하는 방법은 2가지가 있다
1.Runnable interface구현
2.Thread클래스 상속
Runnable 인터페이스를 구현하는 경우에는 해당 클래스를 인스턴스화해서 Thread 생성자에 argument로 넘겨주어야 함run()을 호출하면 Runnable 인터페이스에서 구현한 run()이 호출되므로 따로 오버라이딩 하지 않아도 되는 장점이 있음public class ConsumerRunnable implements Runnable{
int num;
public ConsumerRunnable(int num) {
this.num=num;
}
@Override
public void run () {
System.out.println("#"+num+" start");
for (int i=0; i<1000; i++) {
System.out.println("#"+num+" : "+i);
}
System.out.println("#"+num+" end");
}
}
=> Thread c3=new Thread(new ConsumerRunnable(3));
c3.start();
Thread클래스를 상속받은 경우는, 상속받은 클래스 자체를 스레드로 사용할 수 있음Thread 클래스를 상속받으면 스레드 클래스의 메소드 (getName())을 바로 사용할 수 있지만, Runnable 구현의 경우 Thread 클래스의 static 메소드인 currentThread()를 호출하여 현재 스레드에 대한 참조를 얻어와야만 호출이 가능<currentThread ().getName() 사용>
public class ThreadTest implements Runnable {
public ThreadTest() {}
public ThreadTest(String name){
Thread t = new Thread(this, name);
t.start();
}
@Override
public void run() {
for(int i = 0; i <= 50; i++) {
System.out.print(i + ":" + Thread.currentThread().getName() + " ");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Thread 구현
public class ConsumerThread extends Thread{
int num;
public ConsumerThread(int num) {
this.num=num;
}
@Override =====> run을 override
public void run () {
System.out.println("#"+num+" start");
for (int i=0; i<1000; i++) {
System.out.println("#"+num+" : "+i);
}
System.out.println("#"+num+" end");
}
}
스레드 실행
스레드 실행은
run()이 아닌start()로 호출
call stack -> 실질적인 명령어들을 담고 있는 메모리로 하나씩 거내서 실행시키는 역할 (만약 동시에 두 가지 작업을 한다면, 두 개 이상의 콜 스택이 필요함)run() 메소드를 이용한다는 것은 main()의 콜스택 하나만을 이용하는 것으로 스레드의 활용이 아님 -> start() 메소드를 호출하여 JVM이 스레드를 위한 콜스택을 새로 만들고, context switching 동작동기화
여러 스레드가 같은 프로세스 내의 자원을 공유하면서 작업할 때 서로의 작업이 다른 작업에 영향을 주기 때문에 동기화 필수적
synchronized 키워드로 임계영역을 설정public synchronized void saveMoney(int save){ // 입금
int m = money;
try{
Thread.sleep(2000); // 지연시간 2초
} catch (Exception e){
}
money = m + save;
System.out.println("입금 처리");
}
public synchronized void minusMoney(int minus){ // 출금
int m = money;
try{
Thread.sleep(3000); // 지연시간 3초
} catch (Exception e){
}
money = m - minus;
System.out.println("출금 완료");
}
Sleep사용 -> Running 상태에서 Runnable 상태로
Synchronized 블록 내에서 실행이 되어야 함wait () : 스레드가 lock을 가지고 있으면 lock 권한을 반납하고 대기하게 만듦notify () : 대기 상태인 스레드에게 다시 lock 권한을 부여하고 수행하게 만듦notifyAll () : 잠들어있던 스레드 모두를 깨움Reference
https://gyoogle.dev/blog/computer-language/Java/Thread.html