본문 바로가기

공부일지

231026 (Java)

프로세스와 스레드

  • 프로세스 : 어플리케이션 실행시 운영체제로부터 메모리를 할당 받아 실행되는 것
  • 스레드 : 프로세스 내부에서 진행되는 코드의 흐름

Java의 스레드

  • ToolKit : Window로부터 소리를 제공받아 사용한다.
Toolkit tk = Toolkit.getDefaultToolkit();
tk.beep();
for (int i = 0; i < 5; i++) {
			tk.beep();
			System.out.println("띠링");
			try {
				Thread.sleep(1000 * 2);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
  • for 반복문은 0.0001초 이내에 5번 동작하기 때문에 차이를 알 수 없다.
  • 따라서 thread.sleep이라는 코드가 필요
  • Thread.sleep : 동작 중인 프로세스를 휴지시킨다.
    • thread.sleep은 빨간 줄이 나온다. 트라이 캐치를 설정하는 것이 권장된다.
  • 멀티스레드의 작성
package pack01.testthread;

import java.awt.Toolkit;

public class Ex02_Thread {
	public static void main(String[] args) {
		Runnable run = new Runnable() {
			
			@Override
			public void run() {
				for(int i=0; i<5; i++) {
					Toolkit.getDefaultToolkit().beep();;
					System.out.println("삑");
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			}
		};
		Thread thread = new Thread(run);
		thread.start();
		System.out.println("여기는 메인 메소드 스레드 코드");
	}
}
  • runnable을 상속 받아 코드를 만들고, thread 생성 시 runnable로 만든 class의 인스턴스 객체를 대입하면 새로운 작업 스레드에서 runnable의 코드가 실행될 수 있다.
  • Thread.start로 새로운 스레드에서 작업이 시작된다.
  • throws exception : 트라이캐치가 필요한 코드 작성시 코드 내부에서 오류 처리를 하지 않고 해당 코드를 불러오는 위치에서 오류처리를 하도록 강제하는 코드
    • 메소드에 throws exception을 설정하면 해당 메소드를 호출하는 클래스에서 예외처리(try - catch 등)를 해 주어야 한다.
  • 스레드를 사용하기 위해서는 스레드 객체, runnable 메소드가 필요하다.
  • 스레드를 만들고 스타트 메소드를 실행해야 실제 메소드가 분리되고 동작하게 된다.

테스트

  • 이니셜 스레드 만들기
  • 숫자를 입력받아 해당하는 숫자까지 구구단을 출력하는 쓰레드
package pack02.threadattr;

public class Multi extends Thread {
	int n;
	
	public Multi(int n) {
		this.n = n;
	}

	@Override
	public void run() {
		for (int i = 2; i <= n; i++) {
			for (int j = 1; j <= 9; j++) {
				System.out.println(i + " x " + j + " = " + i*j);
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}
package pack02.threadattr;

import java.util.Scanner;

public class MultiMain {
	static Scanner sc = new Scanner(System.in);

	public static void main(String[] args) {
		
		Multi t = new Multi(inputNum());
		t.start();
		
	}

	public static int inputNum() {
		while (true) {
			System.out.println("숫자를 입력");
			try {
				int a = Integer.parseInt(sc.nextLine());
				return a;
			} catch (Exception e) {
			}
		}
	}
}

스레드의 우선순위

  • 스레드에 우선순위를 지정하여 먼저 실행되도록 할 수 있다.
  • 큰 시간과 작업 공간이 필요한 작업이 아닌 경우 체감이 되지 않는다.
  • 작업 크기가 같다면 랜덤으로 실시될 확률이 크다.
t1.setPriority(Thread.MIN_PRIORITY);

스레드 테스트 2

  • 새로운 패키지에서 진행
  1. 스캐너로 파일 이름을 입력하면 해당 파일을 다운로드 하는 쓰레드를 작성하기.
    • 파일은 1~100%까지 작업을 하고 100%가 되면 종료된다.
    • -1 입력시 프로그램 종료
package pack03.test;

import java.util.Random;

public class Download extends Thread{
	int timer;
	@Override
	public void run() {
		for(int i=1; i<=100; i++) {
			System.out.println(getName()+" 다운로드 중 "+i+"%");
			try {
				Thread.sleep(timer);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println(getName()+" 다운로드 완료");
	}
	
	public Download(String name) {
		this.setName(name);
		this.timer = new Random().nextInt(200)+200;
	}
}
package pack03.test;

import java.util.Scanner;

public class DownloadMain {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			String str = sc.nextLine();
			if(str.equals("-1")) {
				System.out.println("다운로드 프로그램 종료");
				break;
			}
			Download dl = new Download(str);
			dl.start();
		}
	}
}
  1. 경마 게임 만들기
    • 경마 인원을 처음에 입력한다. 2~5인
    • 경마 시작 메뉴를 누르면 랜덤하게 달리기 시작(랜덤하게 증가되어 100이 되는 순간 종료)
    • 먼저 작업이 끝난 순서되로 순위를 할당하고 프로그램은 종료됩니다.
package pack03.test;

public class DTO {
	int[] rank;
	public void setRank(int idx) {
		for(int i=0; i<rank.length; i++) {
			if(rank[i]==0) {
				rank[i]=idx;
				System.out.println(idx + "번 말 " + "완주");
				break;
			}
		}
	}
}
package pack03.test;

import java.util.Scanner;

public class DAO {
	Horse[] horses;
	DTO dto;
	Scanner sc = new Scanner(System.in);
	
	public Horse[] initHorses(int num) {
		Horse[] horses = new Horse[num];
		for(int i=0; i<num; i++) {
			horses[i] = new Horse(i+1, dto);
		}
		return horses;
	}
	

	public DTO initDTO(int num) {
		DTO dto = new DTO();
		dto.rank = new int[num];
		return dto;
	}
	
	public DAO() {
		int num = inputNum();
		this.dto = initDTO(num);
		this.horses = initHorses(num);
	}
	
	public int inputNum() {
		while(true) {
			System.out.println("2~5의 숫자를 입력하세요.");
			int num=0;
			try {
				num = Integer.parseInt(sc.nextLine());
			} catch (Exception e) {
				System.out.println("입력 오류 다시 입력하세요.");
				continue;
			}
			if(1<num&&num<=5) {
				return num;
			} else {
				System.out.println("입력 범위 초과");
			}
		}
	}
	
	public void race() {
		System.out.println("경주 시작");
		for(int i=0; i<horses.length; i++) {
			horses[i].start();
		}
	}
	
}
package pack03.test;

import java.util.Random;

public class Horse extends Thread {
	int idx;
	Random random = new Random();
	DTO dto;
	@Override
	public void run() {
		int run = 0;
		while (true) {
			run += random.nextInt(7) + 1;
			if(run >= 100) {
				break;
			}
			System.out.println(idx + "번 말 " + run + "미터");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		dto.setRank(idx);
		if(dto.rank[dto.rank.length-1]!=0) {
			System.out.println("최종 순위");
			for(int i=0; i<dto.rank.length; i++) {
				System.out.println(dto.rank[i] + "번 말 " + (i+1) + "등!");
			}
		}
	}

	public Horse(int idx, DTO dto) {
		this.dto = dto;
		this.idx = idx;
	}

}
package pack03.test;

public class HorseMain {
	public static void main(String[] args) {
		DAO dao = new DAO();
		dao.race();
	}
}

'공부일지' 카테고리의 다른 글

231030 (Java)  (0) 2023.10.30
231030 (Oracle)  (0) 2023.10.30
231026 (Oracle)  (0) 2023.10.26
231025 (Java)  (0) 2023.10.26
231025 (Oracle)  (0) 2023.10.25