본문 바로가기
JAVA

[JAVA] Thread 구현 방법

by w1z 2024. 4. 27.
  • 하나의 응용프로그램은 운영체제에 의해 process(작업 단위)를 확보하며 응용 프로그램의 실행은 thread(실행 단위)가 담당
  • 기본적으로 main thread에 의해 응용프로그램이 실행됨
  • thread의 개수만큼 실행 단위를 늘어난다 = multi thread에 의한 multi tasking이 가능

→ 동시에 작업하는 것'같은' 효과를 위해서는 여러 개의 Thread를 만들면 됨

  • 주로 네트워크 작업에서 많이 활용되며 자바에서 실행 파일을 직접 실행함
  • Process 간 자원 공유는 불가능, 하나의 Process 내에서 Thread 간 자원 공유는 가능

ex1. process 단위의 실행

package pack_thread;

public class Ex_Thread1 {
	public static void main(String[] args) {
		try {
			Process p1 = Runtime.getRuntime().exec("calc.exe");
		} catch (Exception e) {}
	}
}

ex2. thread 사용하지 않은 경우: 순차적으로 실행

 

 
package pack_thread;

public class Ex_Thread1 {
	public Ex_Thread1() {}
	
	public void run() {
		for(int i=1; i<=50; i++) {
			System.out.print(i + " ");
		}
	}
	
	public static void main(String[] args) {
		try {
			Ex_Thread1 th1 = new Ex_Thread1();
			th1.run();
			Ex_Thread1 th2 = new Ex_Thread1();
			th2.run();
			
		} catch (Exception e) {}
	}
}

스레드 구현 방법

  1. 활성화: start()
  2. 실행
    • 추상클래스 Thread(Runnable을 implement(구현)한)를 extend 후 run 메소드를 오버라이딩(선택) (case3) 또는
    • 인터페이스 Runnable(run()메소드밖에 없음)을 implement 후 run메소드를 오버라이딩(필수)(case4)
    • 두 방법에 큰 차이는 없지만 extends Thread를 하게 되면 다른 클래스 상속받는 게 불가능하기에(다중상속 불가능), implement Runnable을 더 많이 씀(상속도 하나 받을 수 있고 여러 인터페이스 구현이 추가적으로 가능하므로)
  3. 비활성화:
    1. sleep() <-> timeout 또는
    2. wait() <-> notify()

extends Thread → 사용자 정의 thread를 사용한 경우: 랜덤하게 실행

Thread는 java.lang 패키지에 있는 자바의 기본 클래스이므로 import 불필요

package pack_thread;

public class Ex_Thread1 extends Thread{
	public Ex_Thread1() {}
	
	public Ex_Thread1(String name) {
		super(name);
	}
	
	public void run() {
		for(int i=1; i<=50; i++) {
			System.out.print(i + " " + getName() + " "); 
			// 각각 th1, th2 중 어떤 객체의 스레드가 나오나 확인해보자
		}
	}
	
	public static void main(String[] args) {
		try {
			Ex_Thread1 th1 = new Ex_Thread1("one");
			th1.start();
			Ex_Thread1 th2 = new Ex_Thread1("two");
			th2.start();		
			System.out.println("프로그램 종료");
			// 				
		} catch (Exception e) {}
	}
}

**

th1.run()이 아니고 th2.start()임!!

start()가 아닌 run()을 하게되면 멀티태스킹이 아니라 순차적으로 실행됨. 스레드를 사용할 의미가 없겠지

start()는 사용자 정의에 의한 멀티태스킹, run()은 메인 스레드에 의한 싱글태스킹

**

th2.setPriority(MAX_PRIORITY);

//스레드 스케쥴러에게 최대 우선 순위 요청(Max 10. min 1). 확률을 높일 뿐 무조건 요청 승인되진 않음

th1.join(); //th1 스레드가 종료될 때까지 main스레드의 종료를 대기

th1.yield(); //다른 스레드의 수행 요청이 들어오면 현재 스레드의 수행를 일시정지

implements Runnable

package pack_thread;

public class Ex_Thread1 implements Runnable {
	public Ex_Thread1() {}
	
	public Ex_Thread1(String name) {
		Thread t = new Thread(this, name); //생성자 Thread(Runnable Target, String name)
		t.start();
	}
	
	@Override
	public void run() {
		for(int i=1; i<=50; i++) {
			System.out.print(i + " " + Thread.currentThread().getName());
		}
		try {
			Thread.sleep(100);
		} catch (Exception e) {}
	}
	
	public static void main(String[] args) {
		new Ex2Thread2("하나");
		new Ex2Thread2("둘");
	}
}