본문 바로가기

청년취업아카데미/DayLog

[ Java ] Day 03 - ② Thread의 생성

# Thread 생성하는 방법

  1. Thread 클래스로 부터 직접 상속받아 스레드를 생성
  2. Runnable 인터페이스를 사용하는 방법(현재의 클래스가 이미 다른 클래스로 부터 상속 받고 있는 경우)

 

# 1. Thread 클래스로 부터 직접 상속 받아 쓰레드 생성

...더보기
  • Thread 이용
  1. Thread 클래스를 상속받은 뒤, 해당 쓰레드에서 지우너하고 싶은 코드를 run() 메소드에서 오버라이딩 해준다.
  2. 해당 쓰레드를 생성한 후, 쓰레드 객체의 start() 메소드를 호출한다.
  • Thread 작성 및 실행
class ThreadA extends Thread{
	
	@Override
	public void run(){
    	//상위 클래스인 Thread 클래스의 run() 메소드를 오버라이딩하여 쓰레드가 수행해야하는 문장들 기술
    }

}

Class ThreadEx{

	ThreadA ta = new ThreadA();
	ta.start();

}

 

...더보기

Thread 클래스

  • JDK는 스레드를 지원하는 java.lang.Thread 클래스 제공
  • 쓰레드를 생성하기 위해 사용
  • 4개의 생성자를 제공
  1. Thread()
  2. Thread(String s) // 쓰레드의 이름 설정 
  3. Thread(Runnable r)
  4. Thread(Runnable r, String s)
  • Thread 클래스의 메소드
void sleep(long msec) msec에 지정된 밀리초(miliseconds) 동안 대기
void sleep(long msec, int nsec)

msec에 지정된 밀리초+ nsec에 지정된 throws InterruptedException

나노초(nanoseconds)동안 대기

String getName() 스레드의 이름을 반환
void setName() 스레드의 이름을 s로 설정
void start() 스레드 시작시킴, run() 메소드를 호출
int getPriority() 스레드의 우선 순위를 반환
void setPriority(int p) 스레드의 우선 순위를 p 값으로 설정
boolean isAlive() 스레드가 시작되었고 아직 끝나지 않았으면 true를 그렇지 않으면 false 반환
void join() 스레드가 끝날 때까지 대기
void run() 스레드가 실행할 부분을 기술하는 메소드. 하위 클래스에서 반드시 오버라이딩 되어야한다.
void suspend() 스레드가 일시 정지된다. resume()에 의해 다시 시작될 수 있다.
void resume() 일시 정지된 스레드를 다시 시작시킨다.

 

# 2. Runnable 인터페이스를 사용하는 방법

...더보기

현재 클래스가 이미 다른 클래스로 부터 상속을 받고 있는 경우 사용한다.

Runnable 인터페이스는 JDK에 의해 제공되는 라이브러리 인터페이스이다. Runnable 인터페이스에는 run()메소드만 정의되어있다.

public interface Runnable{
	public void run();
}

 

  • Runnable 인터페이스로 쓰레드 생성하는 방법
class RunnableB extends Applet implements Runnable{

	@Override
	public void run(){
	// Runnable 인터페이스에 정의된 run() 메소드를 오버라이딩하여 쓰레드가 수행할 문장들을 기술한다.
	}
}
public class RunnableEx{

(1)
	RunnableB r = new RunnableB();
	Thread t = new Thread(r);
	t.start();

(2)
	RunnableB rb = new RunnableB();
	new Thread(rb).start()
}

 

# 3. Thread 예제

...더보기
  • 클래스 선언부
public class Account {
	String AccName;
	int total;

	Account(int total, String AccName) {
		this.total = total;
		this.AccName = AccName;
	}

	void deposit(int amt, String name) {
		total += amt;
		System.out.println(name + " 예금 : " + amt);
	}

	// synchronized 사용시 동시 접근 막는 다.
	synchronized void withdraw(int amt, String name) {
		if (amt <= total) {
			total -= amt;
			System.out.println(name + " 출금 : " + amt);
			getTotal();
		} else {
			System.out.println(name + "의 출금 요청 " + amt + " 잔액부족 저금좀 해 --> 현재 잔액:" + total);
		}

	}

	void getTotal() {
		System.out.println(AccName + "잔액 : " + total);
	}
}

 

  • 클래스 실행부
class AccountUser extends Thread {
	Account  act;
	boolean   flag;
	public AccountUser (Account act , String name) {
		super(name);
		this.act = act;
	}
	public void run() {
		for( int i = 0; i < 5 ; i ++ ) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();

			} 				
			synchronized(act) { // 스레드 간 자원 동기
				if (flag) act.deposit((int)(Math.random()*10000), getName());
				else act.withdraw((int)(Math.random()*10000), getName()); 
				flag   = !flag;   // flag SWAP
			}
		}
	}
}
public class AccountEx {
	public static void main(String[] args) {
		Account act  = new Account(10000,"국민");
		Account act2 = new Account(15000,"신한");
		AccountUser  au1 = new AccountUser(act,  "옥주현");
		AccountUser  au2 = new AccountUser(act,  "김소현");
		AccountUser  au3 = new AccountUser(act,  "정선아");
		AccountUser  au4 = new AccountUser(act2, "김준수");
		AccountUser  au5 = new AccountUser(act2, "지현우");
		AccountUser  au6 = new AccountUser(act2, "대조영");
		au1.start();
		au2.start();
		au3.start();
		au4.start();
		au5.start();
		au6.start();
	}

}