10월 17일

Yullgiii·2023년 10월 18일
0
post-thumbnail

내일 배움 캠프

Java

5주차 시작!!!!

프로세스 & 쓰레드와
모던 자바에 대해 알려주신다고 한다

프로세스

프로세스 작업 단위
프로세스는 “실행 중인 프로그램”을 의미
OS가 프로그램 실행을 위한 프로세스를 할당해줄때 프로세스안에 프로그램 Code와 Data 그리고 메모리 영역(Stack, Heap)을 함께 할당
Memory (메모리 영역)

  • Stack : 지역변수, 매개변수 리턴 변수를 저장하는 공간
  • Heap : 프로그램이 동적으로 필요한 변수를 저장하는 공간 (new(), mallock())

쓰레드

쓰레드는 프로세스내에서 일하는 일꾼(코드실행의 흐름)
쓰레드의 생성
프로세스가 작업중인 프로그램에서 실행요청이 들어오면 쓰레드(일꾼)을 만들어 명령을 처리
쓰레드의 자원

Java 쓰레드


Java 프로그램 쓰레드는 Java Main 쓰레드부터 실행되며 JVM에 의해 실행

멀티 쓰레드

↕️

싱글 쓰레드

프로세스 안에서 하나의 쓰레드만 실행되는 것
Java 프로그램의 경우 main() 메서드만 실행시켰을때 이것을 싱글 쓰레드

멀티 쓰레드

프로세스 안에서 여러개의 쓰레드가 실행되는 것
멀티 쓰레드 장점

  • 여러개의 쓰레드(실행 흐름)을 통해 여러개의 작업을 동시에 할 수 있어서 성능이 좋아집니다.
  • 스택을 제외한 모든 영역에서 메모리를 공유하기 때문에 자원을 보다 효율적으로 사용할 수 있습니다.
  • 응답 쓰레드와 작업 쓰레드를 분리하여 빠르게 응답을 줄 수 있습니다. (비동기)

멀티 쓰레드 단점

  • 동기화 문제가 발생할 수 있습니다.
    • 프로세스의 자원을 공유 하면서 작업을 처리하기 때문에 자원을 서로 사용하려고 하는 충돌이 발생하는 경우를 의미합니다.
  • 교착 상태(데드락)이 발생할 수 있습니다.
    • 둘 이상의 쓰레드가 서로의 자원을 원하는 상태가 되었을 때 서로 작업이 종료되기만을 기다리며 작업을 더 이상 진행하지 못하게 되는 상태를 의미합니다.(너가 안주면 나도 안줘!안줘!!그럼 배쨰!!!기다릴거야)

Thread & Runnable

Thread

public class TestThread extends Thread {
				@Override
				public void run() {
				// 쓰레드 수행작업
                            
				}
}

main에서 
TestThread thread = new TestThread(); // 쓰레드 생성
thread.start() // 쓰레드 실행

run() 메서드에 작성된 코드가 쓰레드가 수행할 작업

Runnable

public class TestRunnable implements Runnable {
				@Override
				public void run() {
				// 쓰레드 수행작업 
				}
}

...

Runnable run = new TestRunnable();
Thread thread = new Thread(run); // 쓰레드 생성

thread.start(); // 쓰레드 실행
  • Thread를 상속 받아 처리하는 방법은 확장성이 매우 떨어집니다.
  • 반대로 Runnable은 인터페이스이기 때문에 다른 필요한 클래스를 상속 받을 수 있습니다.
    • 따라서 확정성에 매우 유리합니다.

람다식

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            int sum = 0;
            for (int i = 0; i < 50; i++) {
                sum += i;
                System.out.println(sum);
            }
            System.out.println(Thread.currentThread().getName() + " 최종 합 : " + sum);
        };

        Thread thread1 = new Thread(task);
        thread1.setName("thread1");
        Thread thread2 = new Thread(task);
        thread2.setName("thread2");

        thread1.start();
        thread2.start();
    }
}

이건 아직 잘 모르겠다 오늘 배울 후반 부분에 잘 나온다고 하니 그때 좀 더 자세하게 해보도록 하자!

중간 정리 기억할것 멀티스레드는 일의 순서를 모른다!동시에 진행된다 그러니 랜덤하게 된다!@!!!!!

데몬 쓰레드와 사용자 쓰레드

데몬 쓰레드

보조적인 역할을 담당하며 대표적인 데몬 쓰레드로는 메모리 영역을 정리해주는 가비지 컬렉터(GC)
우선 순위가 낮다= 다른 쓰레드에 비해 리소스를 적게 할당받는다.

쓰레드 우선순위

  • 최대 우선순위 (MAX_PRIORITY) = 10
  • 최소 우선순위 (MIN_PRIORITY) = 1
  • 보통 우선순위 (NROM_PRIORITY) = 5
    • 기본 값이 보통 우선순위
  • 스레드 우선순위는 setPriority() 메서드로 설정 가능.
 Thread thread1 = new Thread(task1);
 thread1.setPriority(8);

쓰레드 그룹

메인 쓰레드는 system 그룹 하위에 있는 main 그룹에 포함
모든 쓰레드들은 반드시 하나의 그룹에 포함

쓰레드 상태와 제어

상태Enum설명
객체생성NEW쓰레드 객체 생성, 아직 start() 메서드 호출 전의 상태
실행대기RUNNABLE실행 상태로 언제든지 갈 수 있는 상태
일시정지WAITING다른 쓰레드가 통지(notify) 할 때까지 기다리는 상태
일시정지TIMED_WAITING주어진 시간 동안 기다리는 상태
일시정지BLOCKED사용하고자 하는 객체의 Lock이 풀릴 때까지 기다리는 상태
종료TERMINATED쓰레드의 작업이 종료된 상태

sleep(), interrupt()

sleep()

현재 쓰레드를 지정된 시간동안 멈추게함

  • Thread.sleep(ms); ms(밀리초) 단위로 설정됩니다.
  • 예외처리를 해야합니다.
    • sleep 상태에 있는 동안 interrupt() 를 만나면 다시 실행되기 때문에 InterruptedException이 발생할 수 있습니다.
  • 특정 쓰레드를 지목해서 멈추게 하는 것은 불가능합니다.
interrupt()

일시정지 상태인 쓰레드를 실행대기 상태로 만들어준다.
!Thread.currentThread().isInterrupted() 로 interrupted 상태를 체크해서 처리하면 오류를 방지

join(), yield()

join()

정해진 시간동안 지정한 쓰레드가 작업하는 것을 기다립니다.

  • 시간을 지정하지 않았을 때는 지정한 쓰레드의 작업이 끝날 때까지 기다립니다.

  • 예외처리를 해야합니다.

    • interrupt() 를 만나면 기다리는 것을 멈추기 때문에 InterruptedException이 발생할 수 있습니다.
  • 시간을 지정하지 않았기 때문에 thread가 작업을 끝낼 때까지 main 쓰레드는 기다리게됩니다.

yield()

남은 시간을 다음 쓰레드에게 양보하고 쓰레드 자신은 실행대기 상태

synchronized

한 쓰레드가 진행중인 작업을 다른 쓰레드가 침범하지 못하도록 막는 것을 '쓰레드 동기화(Synchronization)'
동기화를 하려면 다른 쓰레드의 침범을 막아야하는 코드들을 ‘임계영역’으로 설정
임계영역에는 Lock을 가진 단 하나의 쓰레드만 출입이 가능

wait(), notify()(항상 같이 쓰는 한쌍)

침범을 막은 코드를 수행하다가 작업을 더 이상 진행할 상황이 아니면, wait() 을 호출하여 쓰레드가 Lock을 반납하고 기다리게 할 수 있다!
wait()
실행 중이던 쓰레드는 해당 객체의 대기실(waiting pool)에서 통지를 기다림
notify()
해당 객체의 대기실(waiting pool)에 있는 모든 쓰레드 중에서 임의의 쓰레드만 통지받음

뭔말이다냐.....

Lock, Condition

Lock(어려우니 일단 참고만....)

synchronized 블럭으로 동기화하면 자동적으로 Lock이 걸리고 풀리지만, 같은 메서드 내에서만 Lock을 걸 수 있다는 제약
이런 제약을 해결하기 위해 Lock 클래스를 사용

ReentrantLock

재진입 가능한 Lock, 가장 일반적인 배타 Lock
특정 조건에서 Lock을 풀고, 나중에 다시 Lock을 얻어 임계영역으로 진입이 가능

ReentrantReadWriteLock

읽기에는 공유적이고, 쓰기에는 베타적인 Lock
읽기 Lock이 걸려있으면 다른 쓰레드들도 읽기 Lock을 중복으로 걸고 읽기를 수행
읽기 Lock이 걸려있는 상태에서 쓰기 Lock을 거는 것은 허용X. (데이터 변경 방지)

StampedLock

ReentrantReadWriteLock에 낙관적인 Lock의 기능을 추가
낙관적인 Lock : 데이터를 변경하기 전에 락을 걸지 않는 것
낙관적인 락을 사용하면 읽기와 쓰기 작업 모두가 빠르게 처리
낙관적인 읽기 Lock은 쓰기 Lock에 의해 바로 해제 가능
무조건 읽기 Lock을 걸지 않고, 쓰기와 읽기가 충돌할 때만 쓰기 후 읽기 Lock

Condition

모던 자바!

자바8!!!대격변....?

1.함수형 프로그래밍:

함수를 일급 객체로 취급하여 함수의 인자로 전달하거나 결과로 반환할 수 있다.
순수 함수와 불변성을 중요시하는 프로그래밍 패러다임.

2.람다 표현식:

함수형 인터페이스의 구현을 간단한 표현으로 작성할 수 있다.
(a, b) -> a + b와 같은 형식으로 표현된다.

3.스트림 API:

데이터의 연속성을 표현하며, 여러 연산을 체이닝하여 복잡한 데이터 처리를 수행한다.
filter(), map(), collect() 등의 함수를 사용하여 데이터를 가공한다.

4.Null 처리와 Optional:

Null은 자바에서 자주 발생하는 문제점 중 하나이다. 이를 안전하게 처리하기 위해 Optional 클래스가 도입되었다.
Optional을 사용하면 Null 값을 보다 명확하게 처리할 수 있으며, 불필요한 Null 체크를 줄일 수 있다.
Optional.of(), Optional.empty(), Optional.ofNullable() 등의 메서드를 제공한다.

이해가 진짜 안됩니다!!!!!!!!!!!!너무 어려워요

다른강의도 참고 해야겠다...

회고

오늘은 이제 저녁에 특강으로 TIL작성하는 이유와 뭐 이런저런것들의 강의가 있었는데
나는 개발자가 되겠어!할떄부터 작성을 하고 있다보니 어떻게 쓰는지 방법도 뭣도 모르는 상태로 써나간것들이였지만 이젠 좀 더 자세하고 세세하게 정리를 해 나아가며 써봐야겠다는 생각을 하기는 했다. 언제까지 할진 모르지만 내가 스스로를 믿어주지 않는데 누가 나를 믿을것인가.
전반적인 자바 강의를 들었지만 이렇게 속도감있고 빠르게 슈루룩 넘어가는 강의는 정말 드물었던거 같다. 그래서 그런지 아직 잘 감이 안잡히지만 개인 과제가 내일부터 나오니 그것들을 해 나아가면서 한번 제대로 도전해보려한다.

profile
개발이란 무엇인가..를 공부하는 거북이의 성장일기 🐢

0개의 댓글