JAVA/java 공부

[JAVA] thread 592

congs 2023. 9. 12. 01:23

 

thread 592

 

실행(process) → 메모리에 프로그램이 올라감(cpu점유=thread)

  • cpu : 시간을 쪼개서 사용 (시분할시스템)
  • 각각의 프로세스와 thread는 독립적 (다른 프로세스에 영향을 미치지않음)
  • but, 멀티 thread는 한 프로세스에서 사용되는 것이라 함께 멈춤
  • try/catch등의 예외 처리가 필요!

 

1. 사용 과정

  1. 실행 중인 프로그램(process)이 OS(운영체제)로부터 메모리를 할당 받아
  2. → process 상태가 됨
  3. 하나의 프로세스는 하나 이상의 Thread을 가지게 되고,(thread 단위는 실제 CPU가 처리하는 단위)
  4. → 실제 작업을 수행하는 단위는 Thread 단위

 

2. Multi Thread

  • multi thread : 여러 thread가 동시에 수행되는 프로그래밍
    • CPU는 시간을 잘게 쪼개서 thread를 수행하면 ⇒ 사용자들은 동시에 처리하는 듯한 효과를 받음
    붕괴영역 critical section
  • thread는 각각 자신만의 작업 공간을 가짐(context)
    • 각 thread 사이에 공유하는 자원이 있을 수 있음 (자바에서는 static instance)
  • 여러 thread들이 공유하는 자원 중 경쟁이 발생하는 부분 = 붕괴영역 critical section
  • ✨ critical section에 대한 동기화(동기화=순차적 수행)를 구현하여 오류를 방지= public synchronized void mm( ){ }
  • → 다른 접근을 잠시 금지하는 역할
  • = . join()

 

3. Thread.currentThread()

: 현재 실행중인 thread

 

4. Thread 사용방법

1 ) 상속(extends Thread) 구현 Thread

public class ThreadEx01 {

	public static void main(String[] args) {
		/*
		 * thread 구현방식
		 * 1. 상속(extends Thread)
		 * 2. 구현(implements Runnable)
		 * - 모두 run()메서드 구현 필요
		 * */

		System.out.println(Thread.currentThread());//현재 실행중인 thread
		
		MyThread th = new MyThread();
		th.start(); //run()이 실행
		
		MyThread th2 = new MyThread();
		th2.start();
		
	}

}

//1.Thread 클래스를 상속해 실행하는 방법

class MyThread extends Thread{
	//Thread상속시 반드시 run() 메서드 구현필요
	public void run() { //내가 이 thread를 불렀을경우 하는 일
		for(int i=0; i<=200; i++) {
			System.out.println(i + "번째" + getName());//getName()=thread의 이름
		}
	}
}

 

2 ) Runnabke 구현 Thread

public class ThreadEx02 {

	public static void main(String[] args) {
		// 2. Runnabke을 구현해 사용하는 방법
		
		//2-1.사용방법
		MyThread2 mth = new MyThread2();
		Thread th1 = new Thread(mth);
		
		th1.start();
		
		//순차적으로 수행하도록 만들기
		try {
			th1.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		//2-2.사용방법
		Thread th2 = new Thread(new MyThread());
		
		th2.start();
		
		try {
			th2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("main 끝!");
	}

}


class MyThread2 implements Runnable{

	@Override
	public void run() {
		// 반드시 run()을 구현 (=1.상속과 동일)
		for(int i=0; i<=200; i++) {
			System.out.println(i + "번째" + Thread.currentThread().getName());
		}
		
	}
	
}

 


 

.join() ,Runnabke 구현 Thread 사용 예시

package day19;

public class ThreadEx02 {

	public static void main(String[] args) {
		// 2. Runnabke을 구현해 사용하는 방법
		
		//2-1.사용방법
		MyThread2 mth = new MyThread2();
		Thread th1 = new Thread(mth);
		
		th1.start();
		
		//순차적으로 수행하도록 만들기
		try {
			th1.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		
		//2-2.사용방법
		Thread th2 = new Thread(new MyThread());
		
		th2.start();
		
		try {
			th2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println("main 끝!");
	}

}


class MyThread2 implements Runnable{

	@Override
	public void run() {
		// 반드시 run()을 구현 (=1.상속과 동일)
		for(int i=0; i<=200; i++) {
			System.out.println(i + "번째" + Thread.currentThread().getName());
		}
		
	}
	
}

 

Bank ( synchronized이용 )

package day19;

class Bank{
	//계좌의 돈
	private int money = 10000;
	
	// getter,setter
	public int getMoney() {
		return money;
	}
	
	public void setMoney(int money) {
		this.money = money;
	}
	
	//입금
	public synchronized void saveMoney(int save) { //synchronized를 적는 경우) 이 객체에 접근하는 경우, Bank에 접근금지
		int m = this.money;
		try {
			Thread.sleep(3000); //3초 대기
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		setMoney(m + save);
		
	}
	
	//출금
	public synchronized void MinusMoney(int minus) {
		int m = this.money;
		try {
			Thread.sleep(200);//0.2초 대기
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		setMoney(m - minus);
	}
		
}

class Hong extends Thread{
	public void run() { //입금
		System.out.println("입금시작");
		SyncMain.myBank.saveMoney(3000); //static이 가장 먼저 만들어져서 바로 가져오기가능
		System.out.println("3천원 입금 후 : " + SyncMain.myBank.getMoney());
	}
}

class HongWife extends Thread{
	public void run() { //출금
		System.out.println("출금시작");
		SyncMain.myBank.MinusMoney(1000);
		System.out.println("1천원 출금 후 : " + SyncMain.myBank.getMoney());
		
	}
}

public class SyncMain {

	public static Bank myBank = new Bank(); //Bank를 공유영역으로 설정 = 하나의 계좌를 함께 사용
	
	public static void main(String[] args) {
		Hong h = new Hong();
		h.start();
		
		HongWife hw = new HongWife();
		hw.start();
	}

}