Java Thread

Codren·2021년 6월 8일
0

Section 1. Thread

1. 스레드 (Thread)

프로세스를 구성하며 실제 작업이 수행되는 최소 실행 단위




2. 멀티 스레딩 (Multi-Threading)

  • 여러 thread 가 동시에 수행되는 프로그래밍
  • thread 고유의 작업 공간과 thread 사이에 공유하는 공유 자원 존재
  • 동일한 자원을 서로 차지하려는 Race Condition 발생
  • 멀티 스레딩 환경에서 자원의 경쟁이 발생하는 공유 자원 부분을 Critical Section 이라고함




3. Java Thread 생성하는 방법

  • Thread 클래스 상속
  • Runnable 인터페이스 구현
    - 자바에서는 단일 상속만 가능하므로 Thread 를 구현하려는 클래스가 Thread 가 아닌 다른 클래스를 이미 상속 받은 경우에 Runnable 인터페이스 구현




4. Thread 클래스 상속

  • main, th1, th2 총 3개의 스레드가 수행됨
  • main 스레드는 th1, th2 를 실행시키고 종료됨
class MyThread extends Thread{
	
	public void run() {
		
		int i;
		for(i = 0; i<200; i++) {
			System.out.print(i + "\t");
		}
	}
}

public class ThreadTest {

	public static void main(String[] args) {

		System.out.println(Thread.currentThread());		# 현재 블럭에서 수행되는 스레드의 정보 출력 
		MyThread th1 = new MyThread();
		th1.start();
		
		MyThread th2 = new MyThread();
		th2.start();
	}
}




5. Runnable 인터페이스 구현

  • Runnable 인터페이스를 구현 (run 메서드 오버라이딩)
  • Thread 생성자에 Runnable 구현 객체 넘김
class MyThread2 implements Runnable{

	public void run(){
		
		int i;
		for(i=0; i<200; i++){
			
			System.out.print(i + "\t");
	
		}
	}
}

public class ThreadTest2 {

	public static void main(String[] args) {

		System.out.println("main start");
		
		MyThread2 mth = new MyThread2();
		Thread th1 = new Thread(mth);
		th1.start();
		
		Thread th2 = new Thread(new MyThread2());
		th2.start();
        
                Thread th3 = new Runnable() {		# 익명 클래스로 구현 

                    public void run(){

                            int i;
                            for(i=0; i<200; i++){
                                System.out.print(i + "\t");
               	   	    }
		    }
                };
                
		th3.start();
		System.out.println("main end");
	}
}



Section 2. Thread 우선순위

1. Thread 우선순위

  • 스레드가 CPU 를 할당 받는 우선순위
  • Thread.MIN_PRIORITY(=1) ~ Thread.MAX_PRIORITY(=10)




2. Thread 우선순위 적용

  • setPriority() / getPriority() 메서드 사용
class PriorityThread extends Thread{
	
	public PriorityThread(String name) {		# 생성자에서 스레드 이름 지정 

		super(name);
	}

	public void run(){
	
		int sum = 0;
		
		Thread t = Thread.currentThread();
		System.out.println( t + "start");
		
		for(int i =0; i<=1000000; i++){
			
			sum += i;
		}
		
		System.out.println( getName() + " end");
	}
}


public class test {

	public static void main(String[] args) {

	PriorityThread pt1 = new PriorityThread("A");		
        PriorityThread pt2 = new PriorityThread("B");		
        PriorityThread pt3 = new PriorityThread("C");		
        
       	pt1.setPriority(1);					
        pt2.setPriority(5);					
        pt3.setPriority(10);				
                
	pt1.start();						
        pt2.start();						
        pt3.start();							
	}

}

  • 결과
    - A -> B -> C 순으로 실행됐지만 우선순위가 높은 C -> B -> A 순으로 종료가 됨




Section 3. join 메서드

1. 스레드 join 메서드

  • 동시에 두 개 이상의 Thread가 실행 될 때 다른 Thread 의 결과를 참조 하여 실행해야 하는 경우 사용
  • join() 함수를 호출한 Thread가 not-runnable 상태가 감
  • 다른 Thread의 수행이 끝나면 runnable 상태로 돌아옴




2. join 메서드 사용

  • main 스레드와 1부터 50, 51부터 100 까지의 합을 구하는 두 개의 Thread 총 3개의 스레드 존재
  • join 메서드를 호출하지 않으면 main 스레드가 lastTotal 값을 구할 때 나머지 두개의 스레드의 수행 결과가 아직 나오지 않아서 0이 출력됨
  • lastTotal 값을 구하기 전에 main 스레드가 join 메서드를 호출하여 계산 결과가 적용되면 다시 수행
public class JoinTest extends Thread{
	
	int start;
	int end;
	int total;
	
	public JoinTest(int start, int end){
		this.start = start;
		this.end = end;
	}
	
	public void run(){
	
		int i;
		for(i = start; i <= end; i++){
			total += i;
		}
	}
	

	public static void main(String[] args) {

		JoinTest jt1 = new JoinTest(1, 50);
		JoinTest jt2 = new JoinTest(51, 100);
		
				
		jt1.start();
		jt2.start();
		
		try{
			jt1.join();			# jt1 스레드가 종료되어야 main 스레드 수행 재개
			jt2.join();			# jt2 스레드가 종료되어야 main 스레드 수행 재개
			
		}catch (InterruptedException e) {	# jt1 또는 jt2 스레드가 종료되지 않을 경우 예외
			System.out.println(e);
		}
		
		
		int lastTotal = jt1.total + jt2.total;
		
		System.out.println("jt1.total = " + jt1.total);
		System.out.println("jt2.total = " + jt2.total);
		System.out.println("lastTotal = " + lastTotal);	
	}

}



Section 4. Thread 인터럽트와 종료

1. Thread 인터럽트 (Interrupt)

  • 다른 Thread 에 예외를 발생시키는 인터럽트를 보냄
  • not-runnable 상태일 때 interrupt() 메서드를 통해 인터럽트를 걸면 다시 runnable 상태가 됨




2. Thread 종료

  • 실제로 스레드가 쓰이는 경우는 거의 무한 루프로 계속 동작함
  • private 멤버변수로 flag 를 생성하고 while(flag)의 flag 변수값을 false로 바꾸어 종료를 시킴

0개의 댓글