1. JAVA/3). 자바_개념

자바_개념_Day_31

구이제이 2024. 2. 14. 18:03

실제 작업을 하는 곳

cpu는 쓰레드하고만 이야기

쓰레드는 실제로 작업을 하는 것

프로세스의 자원을 이용해서 데이터, 메모리, 자원등을 이용해서 실제 작업을 수행하는 것

cpu를 사용하는 최소 단위

 

#멀티쓰레드

1프로세스

다중 쓰레드 



#

쓰레드보다 코어가 작을 경우

쓰레드를 잘게 쪼개서, 라운드로빙방식(RR방식)

 

쓰레드보다 코어가 많을 경우

 

#

JVM - main - mainThread - 

 

#

 

다른 클래스에 존재하는 메소드를 간단히 사용하는 법 import static을 활용해서 사용한다.




 

throws   //s자 - 던진다. 나를 던진고

자기를 호출한 곳에서 인터럽트인셉션을 떠넘긴다.




thow // s자 안붙음



이 뒤에 있는 곳에 예외를 만들어서 실행해라.















스레드생명주기

 




5. 쓰레드의 동기화

- 임계영역(critical section) :  다수의 쓰레드가 공유 자원을 참조하는 코드 영역

- 동기화 : 다수의 쓰레드가 공유 자원을 충돌 없이 사용할 수 있도록 공유 자원에 

배타적이고 독점적으로 접근할 수 있는 방법

- 임계영역을 동기화 시키는 방법

.메소드에 synchronized 키워드를 지정

public synchronized void 메소드(){ 임계영역 코드 }

 

. 코드의 일부에 synchronized 키워드를 지정

synchronized(공유객체) { 임계영역 코드 }



6. 대기와 통보, 생명주기



쓰레드 스케줄링  :  jvm은 쓰레드의 개수, 쓰레드의 상태, 우선순위 등 쓰레드와 관련된 모든 정보를 관리

쓰레드 객체를 생성하고 start() 메소드를 호출해서 jvm에게 해당 쓰레드를 스케줄링

해달라고 요청



생명주기 :  start()메소드를 호출하면 쓰레드는 실행 대기 상태가 되고 -> jvm이 실행대기 상태에

있는 쓰레드 중에서 하나늘 실행 상태로 만들어 run()메소드를 실행

실행 상태의 메소드는 실행 도중에 다시 실행 대기 상태로 돌아갈 수도 있고 실행을 

종료할 수도 있음, 또 실행을 일시 중시하는 상황도 있을 수 있음

 

 

일시 정지로 보냄 : sleep(long millis) - 주어진 시간 동안 쓰레드를 일시 정지 상태로

 만든다. 주어진 시간이 지나면 자동적으로 실행 대개 상태가 됩니다.

 

    : join () - join()메소드를 호출한 thread는 일시 정지 상태가 된다.

      실행 대기 상태가 되려면, join(0 메소드를 가진 쓰레드가 

 종료되어야 합니다.)

 

  : wait() - 동기화 블록 내에서 thread를 일시 정지 상태로 만든다.

(동기화 - 나 하고 있으면 너 멈춰야되, 일방해하지마)

(비동기화 - 내가멈추면 너도 멈춰야된다.

내가 하면 너도 해야되,같이일하자)

 

일시 정지에서 벗어나기 : interrupt() - 응급상황 일시정지 상태일 경우,

 interruptedException를 발생시켜 실행 대기 상태 또는 종료 상태로 만든다.

 

  : notify() - wait()메소드로 인해 일시정지 상태인 thread를 실행 대기

  : notifyAll() - 위의 문장과 동일

 

실행 대기로 보냄 : yield() - 실행 상태에서 다른 thread에게 실행을 양보하고

  실행 대기 상태가 됩니다.

 

(thread에 속하지 않고)Object에 속하다 wait, notify, notifyAll 



ex) 요리사(Cook)와 손님(Customer)의 관계 - 쓰레드의 협업

    요리(Dish)는 5개를 만들어 제공할 예정, 손님도 5가지의 요리를 먹을 것임

    요리한 음식이 없을 때는 요리사가 요리를 해야 고객이 음식을 먹을 수 있고, 

    한 번에 한 접시씩 요리사와 고객 사이에 오고 간다고 가정

    음식은 공유 자원이 되고, 요리사와 고객은 쓰레드

  고객은 음식을 먹은 후 요리사에게 통보(notify())해야 하고, 요리된 음식이 없다면 대기(wait())해야 함

  요리사는 음식을 요리 한 후 고객에게 통보(notify()) 해야하고, 요리된 음식을 고객이 먹고 있다면 대기(wait())

 

 

wait()

notify()

notifyAll()



7. 쓰레드 풀(thread pool)

- 동시에 실행하는 쓰레드의 개수 제한(thread 개수가 많아지면 그에 따른 thread 객체 생성과 스케줄링 등으로 cpu와 메모리에 많은 부하가 발생할 수 있음)

- 제한된 개수의 쓰레드를 JVM이 관리하도록 맡기는 방식

- 개발자가 쓰레드를 생성할 필요가 없음

  실행할 작업을 쓰레드 풀에 전달하면 JVM이 쓰레드 풀의 

  유휴 쓰레드중 하나를 선택해서 쓰레드를 실행

 

  ExecutorService exec = Executors.newCachedThreadPool();

  exec.execute("쓰레드객체");

 

  맨 마지막에   exec.shutdown();

      void shutdown() : 현재 처리 중인 작업과 남아 있는 모든 작업을 처리한 후 쓰레드 풀 종료

      List<Runnable> shutdownNow() : 현재 처리 중인 작업을 중지시키고 쓰레드 풀을 종료






◐.지난예제

public class HellJavaThread implements Runnable { //exteds Thread

@Override

public void run() {

 

for(int i = 0 ; i <= 5 ; i++) {

 

//sleepShow(500); 메소드를 활용해서, 처리 할 수 있다.

 

try { //지연 시간

Thread.sleep(500);

} catch (InterruptedException e) {

System.out.println("예외 발생");

}

 

 

 

 

System.out.print("Hello!! ");

}

}

 

//Thread는 Runnable을 구현하고 있다.

//throws - 예외를 던져주었다.

 

public static void sleepShow(long num) { //밀리초라서, long형을 받음

//클래스명.메소드를 입력하면, 다른곳에서도 사용가능하다.

//인스턴스의 영역과 스타틱 영역을 구분하는 것이 필요하다.

try {

Thread.sleep(num);

} catch (InterruptedException e) {

System.out.println("예외 발생");

}

 

 

}

}



public class HelloJavaThreadMain {

public static void main(String[] args) {

System.out.println("** main thread **");

 

//# Thread 객체 생성

Runnable h = new HellJavaThread();

Thread ht = new Thread(h);

ht.setDaemon(true); //(보조 쓰레드)데몬 쓰레드로 설정 , start메소드보다 앞에 있어야한다.

 

//# Thread 실행

ht.start();

 

//# main thread 작업

for(int i = 1 ; i <= 5; i++) {

 

try {

Thread.sleep(500);

} catch (InterruptedException e) {

System.out.println("예외 처리");

}

 

System.out.println(" java ");

 

 

}

 

System.out.println("** main thread 종료 **");

 

 

}

}





◐.스레드풀

 

public class ThreadPoolThreadMain {

public static void main(String[] args) {

System.out.println("** 메인 부분 실행... **");

Thread runableThreadPool = new Thread(new Runnable() {

 

 

 

@Override

public void run() { //익명구현객체

 

for(int i = 1 ; i <= 5; i++) {

System.out.println("안녕!! ");

 

try {

Thread.sleep(1000);  //예외를 던져놔서 여기서 처리해야한다.

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}//try ~ catch

}//for

}//run

});

 

 

//# Thread Pool 생성 - 내가 하는 것 아니라 JVM이 스타트한다.

ExecutorService exec = Executors.newCachedThreadPool();

exec.execute(runableThreadPool);

 

//# 메인 부분 작업

System.out.println("** main **");

for(int i = 1; i <= 5; i++) {

System.out.println("즐거운 시간~~ ");

 

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

System.out.println("예외 발생");

}

 

}

 

System.out.println("** 메인 끝 **");

 

//# Thread pool 종료

exec.shutdown(); // 이것이 호출 되지 않으면 종료가 되지 않습니다.

}

}




◐.쓰레드의 ‘join’의 사용법

 

public class CalcThread extends Thread {

private int sum;

public int getSum() {

return sum;

}

public void setSum(int sum) {

this.sum = sum;

}

 

@Override

public void run() {

for(int i = 1; i<= 100; i++) {

sum += i;

}

}

 

 

}

 

public class CalcThreadMain {

public static void main(String[] args) {

//tread를 사용법

//음악플레이어 - 재생 및 일시정지

 

 

 

 

/*

System.out.println("** main **");

 

CalcThread cal = new CalcThread();

cal.start();

 

System.out.println("--------------");

System.out.println("1-100까지의 합 : "+ cal.getSum()); // o이 출력된다.

//계산하고 있는 중에 이미 결과값이 나온 경우이다.

*/

 

System.out.println("------------------------------");

 

 

System.out.println("** main **");

 

CalcThread cal = new CalcThread();

cal.start();

 

 

try {

cal.join(); //thread의 모든 작업을 끝나기 전까지 '일시정지'

//join을 자기를 호출한 메소드를 멈춘다.

} catch (InterruptedException e) {

System.out.println("예외 발생");

}

 

 

 

System.out.println("--------------");

System.out.println("1-100까지의 합 : "+ cal.getSum()); // o이 출력된다.

//계산하고 있는 중에 이미 결과값이 나온 경우이다.

 

 

 

 

}

}





◐.동기화



임계영역 - 여러곳에서 공통적으로 쓰이는 것(여러쓰레드가 공통으로 쓰는부분)

 

// 요리사 - thread

public class Cook implements Runnable {

private final Dish dish; //final설정시 변경불가하다. (선언만 한 상태- 초기화는 생성자에서)

 

public Cook(Dish dish) {

this.dish = dish; // 초기화

}

 

//(int i) : 음식 종류

private void cooking(int i) throws InterruptedException { // 호출하는 쪽에서 처리하라고 던졋다.(throws)

 

//공유 자원을 동기화 - 작업시 못들어온다

// - 요리사와 고객이 음식을 공유 하기 때문에 동기화 시킴

synchronized(dish) { //동기화 블록

while(!dish.isEmpty()) { //빈 접시가 아니면

dish.wait(); // 기다려라

}

 

//빈 접시가 아니면 음식을 먹어 접시를 비우면 된다

dish.setEmpty(false);

System.out.println(i + "번재 음식이 준비되었습니다.");

dish.notify(); // wait()로 인해 일시정지 상태인 경우 실행 대기 상태로 만들기

  // 손님에게 요리 다 되었다고 통보

 

}

}

 

 

 

@Override

public void run() {

for(int i = 1 ; i <= 5; i++) { //5가지 요리를 차례로 먹는다.

try {

cooking(i);

 

Thread.sleep(200);

} catch (InterruptedException e) {

System.out.println("예외 발생");

}

}

}

}




public class Customer implements Runnable {

 

private final Dish dish; //final설정시 변경불가하다. (선언만 한 상태- 초기화는 생성자에서)

 

public Customer(Dish dish) {

this.dish = dish; // 초기화

}

 

//(int i) : 음식 종류

private void eat(int i) throws InterruptedException { // 호출하는 쪽에서 처리하라고 던졋다.(throws)

 

//공유 자원을 동기화 - 작업시 못들어온다

// - 요리사와 고객이 음식을 공유 하기 때문에 동기화 시킴

synchronized(dish) { //동기화 블록

while(dish.isEmpty()) { //빈 접시면

dish.wait(); // 기다려라

}

 

//빈 접시가 아니면 음식을 먹어 접시를 비우면 된다

dish.setEmpty(true);

System.out.println(i + "번째 음식을 먹었습니다.");

dish.notify(); // wait()로 인해 일시정지 상태인 경우 실행 대기 상태로 만들기

  // 요리사에게 음식을 다 먹었다고 통보

}

}

 

 

 

@Override

public void run() {

for(int i = 1 ; i <= 5; i++) { //5가지 요리를 차례로 먹는다.

try {

eat(i);

 

Thread.sleep(200);

} catch (InterruptedException e) {

System.out.println("예외 발생");

}

}

}

}



public class Dish {

private boolean empty = true;

 

public boolean isEmpty() { // boolean형 getter에는 is로 명명하는 것이 좋다.

return empty;

}

 

public void setEmpty(boolean emprty) {

this.empty = empty;

}

 

 

 

 

}

 

public class DishThreadMain {

public static void main(String[] args) {

final Dish d = new Dish();

 

new Thread(new Cook(d)).start();

new Thread(new Customer(d)).start();

 

}

}

 






 

'1. JAVA > 3). 자바_개념' 카테고리의 다른 글

자바_개념_Day_33  (0) 2024.02.19
자바_개념_Day_32  (0) 2024.02.15
자바_개념_Day_30  (0) 2024.02.13
자바_개념_Day_29  (1) 2024.02.08
자바_개념_Day_27  (1) 2024.02.06