2022.08.26/자바 정리/스레드/DBMS

Jimin·2022년 8월 28일
0

비트캠프

목록 보기
30/60
post-thumbnail
  • 스레드 사용법(com.eomcs.concurrent.*)(계속)
    • 스레드 라이프사이클
    • 크리티컬 섹션과 스레드 안전
    • 뮤텍스와 세마포어
    • 자바에서 뮤텍스를 다루는 방법
  • DBMS 사용법
    • Database와 DBMS
    • MariaDB 설치와 설정

메인스레드와 하위스레드 종료

  • 메인스레드가 다른 스레드들보다 먼저 종료되더라도 다른 스레드가 종료될 때까지 JVM은 종료되지 않는다.
  • 메인스레드가 종료되더라도 메인스레드가 실행한 자식스레드가 종료될 때까지 main스레드를 실행시킨 프로세스인 JVM은 종료되지 않는다.

스레드의 생명주기(lifecycle)

  • 생명주기: 생성 → 소멸
  • Running : CPU Scheduling 대상 ⇒ CPU를 받을 수 있는 상태
  • Not Runnable : CPU Scheduling 대상에서 제외 ⇒ CPU를 받지 않는 상태
  • 스레드를 시작시키는 순간 Running 상태로 접어든다.
    • Running 상태는 실행하고 있는 상태 뿐만 아니라, CPU를 받을 수 있는 상태이기도 하다.
    • CPU는 OS의 관리 정책(CPU Scheduling)에 따라 스레드나 프로세스에 배분된다.
  • run() 메서드 종료 후 다시 Running 상태로 돌아갈 수 없다.
    → 즉, 죽은 스레드는 다시 살릴 수 없다.
    ⇒ 새로 스레드를 만들어 실행하는 방법밖에 없다!
  • thread.join()을 하면 thread가 종료할 때까지 main 스레드가 대기한다.
  • Thread.sleep(3000)
    • 3초 동안 main 스레드가 잠든다.
    • 3초 동안 not runnable 상태로 만든다.
    • 3초가 지나면(timeout) 다시 "main" 스레드는 CPU를 받아 실행할 수 있다.
    • sleep()을 호출하면 그 순간에 실행하는 스레드를 잠들게 한다.
    • Sleep을 하면 CPU가 남아돌아도 CPU를 사용하여 실행시키지 않는다.

스레드와 프로세스의 실행: 실체와 이해

1. 실체:

OS가 프로세스나 스레드의 명령을 가져와서 CPU에 넣어서 실행한다.
명령어들을 CPU에 가져와서 실행하는 것
OS가 CPU 스케쥴링 실행 상태에서 작동

2. 이해:

선점형 운영체제: CPU 사용을 OS가 온전히 점유하여 관리
운영체제가 CPU를 프로세스에게 줬다가 뺐다가 스레드에게 줬다가 뺐다가 하며 관리한다.


CPU Racing(CPU 쟁탈전)

  • 여러 프로세스나 스레드들이 CPU 사용권을 놓고 경쟁하는 것
    → 실체! OS가 CPU 스케줄링 정책에 따라 결정한다.

  • 프로세스 스케줄링 → Round Robin 또는 Priority+Aging


모든 스레드는 이름이 존재한다.
사용자가 설정하지 않으면 내부에서 알아서 생성된다.


같은 메모리를 여러 스레드가 동시에 접근할 때 문제점

여러 스레드가 동시에 같은 변수에 접근할 때 다른 스레드의 작업을 덮어쓰는 문제가 발생한다!

public class ExamThread {

  static class MyList {
    int[] values = new int[100];
    int size;

    public void add(int value) {
      // 여러 스레드가 동시에 이 메서드에 진입하면 
      // 배열의 값을 덮어쓰는 문제가 발생한다.
      // 이렇게 여러 스레드가 동시에 접근했을 때 문제가 발생하는 코드 부분을
      // "Critical Section" 또는 "Critical Region" 이라 부른다.
      if (size >= values.length) {
        delay();
        return;
      }
      delay();
      values[size] = value;
      delay();
      size = size + 1;
      delay();
    }

    ...
    
  }

  static class Worker extends Thread {
    
    ...

    @Override
    public void run() {
      for (int i = 0; i < 20; i++) {
        list.add(value);
      }
    }
  }

  public static void main(String[] args) throws Exception {
    MyList list = new MyList();

    Worker w1 = new Worker(list, 111);
    Worker w2 = new Worker(list, 222);
    Worker w3 = new Worker(list, 333);

    w1.start();
    w2.start();
    w3.start();

    Thread.sleep(10000);

    list.print();
  }

}

예를 들어, 인덱스 23에 w1과 w3이 동시에 접근해서 배열 값을 삽입하려고 한 것이다.
w1이 값을 넣고 Delay에 걸려서 size를 증가시키지 못했는데 w3에게 cpu 사용권을 뺏겼다. 그래서 인덱스 23의 값이 최종적으로 333으로 덮어지게 된다.
그 다음에 w3에서 size가 커지고, 다시 cpu 사용권을 w1에게 뻇겨서 size가 또 커져서 인덱스가 건너뛰게 된다.

  • add() 메소드의 경우처럼 여러 스레드가 동시에 코드를 실행할 때 문제가 발생하는 코드 블록을 "치명적인 영역"이라 부른다.
    Critical Region = Critical Section = 여러 스레드가 충돌할 수 있는 코드 블록
  • 어떤 코드에 문제가 발생하는가?
    같은 메모리(변수)를 동시에 접근하여 값을 변경할 때, 문제가 발생한다.
    즉, 다른 스레드가 쓴 값을 덮어 쓸 수 있다.
    또 공유 변수의 계산도 순차적이 아니라 동시에 진행되어 중복될 수 있다.
  • 해결책?
    한 번에 한 스레드만이 접근하도록 제한하면 된다.
    → Mutual Exclusive(상호배제) ⇒ Mutex
    화장실에 한 명만 들어갈 수 있는 것처럼!

상호배제 기법

Semaphore(n): n개까지만 허용, 나머지는 배제

예)
Semaphore(3)
Semaphore(1) ⇒ Mutex

자바에서는 Mutex를 문법으로 지원해준다!
→ synchronized

synchronized로 설정한 스레드는 한 번 실행에 한 스레드밖에 불가능하지만,
순서는 운영체제 맘이라 다른 애가 start() 먼저해도 순서는 뒤섞일 수 있다. 단지 한 번 시작한애가 있으면 다른애가 동시에 실행이 안되는 것이다.

  • Critical Section에 오직 한 개의 스레드만 접근하게 하면 비동기로 인한 문제가 발생하지 않는다.
    ⇒ 즉 동기화로 처리한다.
  • 동기화?
    • 여러 스레드가 동시에 실행하는 것이 아니고 여러 스레드가 순차적으로 접근하는 것.
    • 단 순차적으로 실행한다는 것은 동시 실행의 이점을 버리는 것이기 때문에 스레드를 사용하기 전의 상태와 같다. 기존의 실행 방식 처럼 실행 시간이 많이 걸린다.
  • synchronized
    • critical section 구간에 이 키워드를 붙이면, 오직 한 번에 한개의 스레드만이 접근할 수 있다.
      → 병목현상 발생가능, 그래도 데이터 덮어씌워지는 것보다는 낫다.
    • 즉 critical section을 mutex 구간으로 설정한다.
    • 이 키워드가 붙은 블록(method)은 오직 한 번에 한 개의 스레드만이 접근할 수 있다.
    • 먼저 접근한 스레드가 나가야만 다음 스레드가 진입할 수 있다.

한 번에 한 스레드만 진입하도록 메소드 전체가 아니라 일부 코드만 설정할 수도 있다.

// 동기화 블록
synchronized(스레드가 공유하면 안되는 객체){

}

여러 스레드 동시 실행 비교1

1. 비동기 실행

2. 메서드 동기 실행

3. 블럭 동기 실행


서버와 멀티 스레드, 클라이언트 관계

클라이언트에서 요청을 보내면, 서버에서 각각의 클라이언트들에게 각각의 스레드를 생성해주고, 각각의 클라이어트들은 이 스레드와 통신하게 된다.


ServerApp을 DBMS로 교체하기

ServerApp:

데이터 관리(CRUD)

DBMS:

DataBase Management System (데이터 관리 전문 서버 어플리케이션)

DataBase와 DBMS

ex)
Oracle - Oracle DBMS
MS - MS SQL
IBM - DB2
Oracle - MySQL
개발 커뮤니티 - Maria DB(MySQL 오픈 소스)
한국 - Cubid, Altibase, Tibero

DBMS와 SQL

SQL

명령 문법을 통일 → SQL(Structed Query Language) 구조를 갖춘, DBMS에 명령을 내릴 때 사용하는 문법

Q. 왜 DBMS마다 전용 문법이 있는가?

→ DBMS마다 특별한 기능이 있다. → DBMS만의 특별 기능을 사용할 문법이 필요하다.

MariaDB Server와 Client

profile
https://github.com/Dingadung

0개의 댓글