본문 바로가기

자바

day22

쓰레드 (thread) - 작업자,작업 스케줄러에 의해 시간을 배정 받아 CPU에서 작업할 수 있는 단위 -> 동시 실행이 가능하다. 

                                   **APP**을 만든다고 가정하면  
ex) 프로세스(회사)        - 스레드(기획자)   =>   기획서
         - 스레드(디자이너) =>  디자인
         - 스레드(개발자) =>     코딩
 만약 혼자 APP을 만들 경우, 단계에 맞게 하나씩 차례차례 처리해야 되므로 시간이 많이 걸리지만 // 여러 사람이 각 단계에 맞는 일(작업)을 부여받아 동시에 맡은 작업을 처리하므로 시간을 단축할 수 있다. 

하지만 쓰레드가 특정 변수를 참조할 때 생기는 동시성의 문제가 생기기 때문에 동기화 처리를 통해 안전하게 처리가 가능하다. 


프로세스에 할당된 메모리 영역에서 실행 / 프로세스에 할당된 시스템 리소스 공유 

자바에서 스레드를 사용하는 이유는 비동기적 작동 방식(독립스레드)에 대한 개념이 없음
• 프로그래밍 방식이 자바에서는 사용이 가능하지 않음
• 비동기적 작동 방식 구현 : ‘스레딩 기술의 사용 방법’ 숙지

– 자바가 실행되는 기반인 자바가상머신(Java virtual machine, 이하 JVM) 자체가 하나의 ***'프로세스'***임
• 언어적 차원 : 스레드의 동기화 지원 가능
• 다중 스레드 프로그램을 쉽고 명료하게 만들 수 있음

-다중 쓰레드
– 동기화 메소드들을 기본적인 키워드로 제공함으로써 자바 언어 수준에서 다중 쓰레드 지원
– 자바 API : 쓰레드를 지원해주기 위한 쓰레드 클래스 존재
– 자바 런 타임 시스템 : 모니터와 조건 잠금 함수 제공
– 시분할 기법(Time-Shared)
• 멀티태스킹 및 멀티스레드를 가능하게 하는 기법
• 아주 짧은 시간 간격을 두고 여러 개의 프로그램을 전환하면서 실행
• 빠른 속도 때문에 두 개 이상의 프로그램이 동시에 실행되는 처럼 느껴짐
• 프로그램의 실행을 전환하는 것은 OS가 담당함

–  다중 스레드의 이점
• 자원을 효율적으로 사용할 수 있음
• 사용자에 대한 응답성이 향상됨
• 작업이 분리되어 코드가 간결함

–  다중 스레드의 단점
• 동기화에 주의해야 함
• 교착상태가 발생하지 않도록 주의해야 함
• 각 스레드가 효율적으로 고르게 실행될 수 있게 해야 함

쓰레드의 구현과 실행 
1.Thread 클래스를 상속 - 별도의 쓰레드 생성을 위해서는 별도의 쓰레드 클래스를 정의해야 한다.

2.Runnable interfaces를 구현 - 다중 상속을 위해서 
-Runnable 인터페이스를 구현하는 클래스의 인스턴스를 대상으로 Thread 클래스의 인스터를 생성한다. 상속할 클래스가 존재할 때 유용하게 사용됨 

start()
run()
join()
sleep() -> 기본값은 1/1000s[초]

Runnable 상태의 쓰레드만이 스케줄러에 의해 스케줄링이 가능하다.
그리고 앞서 보인 sleep, join 메소드의 호출로 인해서 쓰레드는 Blocked 상태가 된다. 
한번 종료된 쓰레드는 다시 Runnable 상태가 될 수 없지만, 
Blocked 상태의 쓰레드는 조건이 성립되면 다시 Runnable 상태가 된다.

모든 쓰레드는 스택을 제외한 메소드 영역과 힙을 공유한다. 
따라서 이 두 영역을 통해서 데이터를 주고 받을 수 있다.
스택은 쓰레드 별로 독립적일 수 밖에 없는 이유는, 쓰레드의 실행이 메소드의 호출을 통해서 이뤄지고, 
메소드의 호출을 위해서 사용되는 메모리 공간이 스택이기 때문이다.

***************************************************동기화(synchronized)*************************************************
 -한 번에 하나의 쓰레드만 객체에 접근할 수 있도록 객체에 락(lock)을 걸어서 데이터의 일관성을 유지하는 것
동기화처리 - 하나의 스레드가 조작하고 있는 변수를 다른 스레드가 조작하지 못하도록 동기화가 필요함.
동기화에 사용되는 인스턴스는 하나이며, 이 인스턴스에는 하나의 열쇠만이 존재한다. 

쓰레드를 이용한 예제
package ex.th;

import javax.swing.JOptionPane;

public class HighLowMain {
	public static boolean check = false;

	public static void main(String[] args) {

		Count ct = new Count();
		CheckNumber num = new CheckNumber();
		// 4.10초 이전에 맞추면 미션 성공, 10초가 지나면 프로그램 종료하는 흐름으로 만드리
		num.start();
		ct.start();
	}
}

// 3.10초 카운팅은 스레드를 이용해서 처리
class Count extends Thread {

	@Override // 쓰레드 클래스를 상속시 run() 메서드를 오버라이딩, 구현부를 작성해준다.
	public void run() {
		for (int i = 10; i > 0; i--) {
			// 10초이내에 정답입력시
			if (HighLowMain.check) {
				System.out.println("미션 성공입니다.");
				return;
			}
			System.out.println(i);
			try {
				// 1초 간격
				sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		System.out.println("입력시간 초과입니다.");
		System.out.println("10초이내에 정답을 못 맞췄으므로 프로그램이 종료됩니다.");
		System.exit(0);
	}
}

class CheckNumber extends Thread {

	@Override
	public void run() {
		// 1.1~100 사이의 랜덤 숫자를 설정합니다.

		int random = (int) (Math.random() * 100) + 1;

		System.out.println(random);

		// 2.사용자에게 숫자를 입력 받고, 랜덤 숫자와 비교하고, 높은 숫자인지 낮은 숫자인지 출력
		
		while (!HighLowMain.check) {
			String answer = JOptionPane.showInputDialog("숫자를 입력해주세요: ");
			int num = Integer.parseInt(answer);
			int result = num - random;
			if (result > 0) {
				System.out.println("낮은 숫자를 입력해주세요.");
			}else if(result < 0) {
				System.out.println("높은 숫자를 입력해주세요.");
			}else {
				System.out.println("정답입니다.");
				HighLowMain.check =true;
				return;
			}
		}
	}
}

'자바' 카테고리의 다른 글

day23  (0) 2021.06.13
day21  (0) 2021.06.13
Day20  (0) 2021.06.01
Day19  (0) 2021.05.31
Day18  (0) 2021.05.28