본문 바로가기
개발/자바

(Java)12일차, 자바 쓰레드(Thread)

by kakk789 2022. 4. 12.

자바 쓰레드 (Thread)

  • 쓰레드 : 실행중인 메소드
  • 멀티쓰레드 : 두개이상의 메소드를 가능하다면 공평하게 실행시키는 프로그래밍 방식
  • 쓰레드는 보통 실시간으로 갱신이 필요하거나, 움직이는 그래픽을 표현할 경우 등 사용
class Person extends Thread{
}
1. Thread를 상속받아 공평하게 실행 시키고자 하는 작업 필요 시 run을 오버라이딩
2. start()메소드를 호출하여 가능하다면 최대한 공평하게 일을 시킨다

Runnable 인터페이스

  • 어떤 클래스가 이미 다른 클래스를 상속 받고 있는 상황에서 Thread 사용하고 싶은 경우 Runnable 인터페이스를 구현하여 사용하면 된다
class Person implements Runnable{
}
동일하게 쓰면되는데 Runnable은 start()가 없다, 그럼 run()을 어떻게 실행시키나?
Runnable을 구현받아 쓰레드를 사용하는 경우 쓰레드를 가동 시키기 위해선 Thread 객체로 포장하여 start() 호출

Runnable의 구현 할 메소드

run() 밖에 없음

Thread 생성자에 보면 Runnable 객체를 넘길 수 있다.

이걸 이용하여 아래 코드와 같이 표현

		Person p1 = new Person("홍길동");
		Person p2 = new Person("홍길동");
		
//		p1.start(); // 에러 발생
//		p2.start(); // 에러 발생
		
		Thread t1 = new Thread(p1); t1.start();
		Thread t2 = new Thread(p1); t2.start();
//		(new Thread(p1)).start(); 이런식으로 표현해도됌

쓰레드의 우선순위

setPriority (int newPriority)

MAX_PRIORITY    10   (우선 순위 가장 높음)
MIN_PRIORITY     1    (우선 순위 가장 낮음)
NORM_PRIORITY  5    (우선 순위 중간)
  • 우선순위가 높다 하여도 무조건 먼저 실행되지 않음. 단순히 요청하는 개념

쓰레드 사이의 통신 (nofity, wait)

  • 쓰레드를 가동하면 가.능.하.면 서로 공평하게 실행되게 끔 스케쥴링 됨.
  • 반드시 공평한 것은 아님. 만약 반드시 공평하게 동작하려면 쓰레드끼리 통신하여 상대 쓰레드가 종료될 때까지 기다리고, 완료 시 상대 쓰레드를 깨워줘야함
  • 최상위 Object객체의 notify(), wait()를 사용
  • wait() 상대 쓰레드 종료시 까지기다림
  • notify() 내 작업 완료 시 상대에게 알려줌

임계영역 (Critical Section)

  • 두개 이상의 쓰레드가 어떠한 변수를 공유하고 있을 때 동시에 두개의 쓰레드가 접근할 수 없고 한번에 하나의 쓰레드에게만 접근하도록 하는 영역 영역
  • 아래와 같이 메소드 형식으로 락을 걸어준다. 이게 무슨 말이냐면 'int num'을 여러 쓰레드에서 조작해야할 때 해당 변수를 조작 할 임의의 메서드를 만들고 메서드 명 앞에 synchronized 키워드를 붙힌다. 
  • synchronized 키워드가 붙은 메서드에서만 쓰레드가 특정 조작을 변수를 조작할 것임을 약속하는 개념이다.
  • 이제 makeNumber() 함수를 먼저 호출한 녀석만 해당 영역을 컨트롤 할 수 있음.
임계 영역에 접근하는 메소드에 synchronized 키워드를 붙여 임계영역을 설정
public synchronized void 함수명() { }

누군가가 synchronized 키워드 붙은 makeNuber()를 호출하면 딴 쓰레드는 해당 영역 사용 불가.

wait()와 notify로 해당 영역을 다 사용했음을 알리는 코드를 짤 수 있음.

notify()가 호출 되는 영역 사용 끝이되고 다른 쓰레드로 넘겨버림

2022.04.14 - [분류 전체보기] - Wait And Notify, synchronized 예시

	private int num;

	boolean isNew; 
	public synchronized void makeNumber() {
		while(isNew) {
			try {
				wait();	
			}
			catch(Exception e) {

			}
		}
		num = 1;
		System.out.println("생산자가 새로운 제품을 출력하였습니다. "+ num);
		isNew = true;
		notify();
	}

join() 함수

  • 자바 쓰레드 실행시 특이점이 있는데 약 쓰레드가 5개라면 컴파일러가 알아서 스케쥴링을 해주는데, 이때 쓰레드가 아닌 명령어가 먼저 실행될 수도 있음 (아래 예시에서 join이 없다면 뜬근없이 sysout이 출력이 되버림
  • 그래서 쓰레드가 모두 끝날 때 까지 기다리는 함수 join()을 사용해야함

2022.04.12 - [알고리즘 문제 풀이/Power JAVA] - p729) 문제 1번 A,B,C 를 문제와 같이 출력하시오

		Account account = new Account();
		
		Contributor c1 = new Contributor("홍길동", account);
		Contributor c2 = new Contributor("김유신", account);
		Contributor c3 = new Contributor("김구", account);
		Contributor c4 = new Contributor("윤봉길", account);
		Contributor c5 = new Contributor("박지성", account);
		
		c1.start();
		c2.start();
		c3.start();
		c4.start();
		c5.start();
		try {
			c1.join();
			c2.join();
			c3.join();
			c4.join();
			c5.join();
		}catch (Exception e) {
			// TODO: handle exception
		}

		System.out.println("최종 모금액:" + account.getBalance());

inner 클래스

  • 클래스내부에 또 클래스를 선언할 수 있는데 이렇게되면 멤버 변수를 공유할 수 있다는 장점이 있다.
  • 쓰레드를 이너클래스로 생성하게 되면 객체생성 시에 
    부모클래스 객체명 = new 자식클래스(); 형식으로 사용하는 듯 싶다.
    ( Thread t = new MyThread(); )

 

반응형

댓글