일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- w3schools
- edwith
- 상속
- 데이터베이스 모델링
- CS 기초
- exception
- 모두를 위한 컴퓨터 과학
- CS기초지식
- SW
- ERD
- 이진법
- Computer Science
- CS 기초지식
- 삼성청년SW아카데미
- Java Programming
- 부스트코스
- 면접을 위한 CS 전공지식 노트
- 객체지향
- WebProgramming
- 기초프로그래밍
- 예외처리
- til
- 모두를 위한 컴퓨터 과학(CS50)
- 관계형 데이터베이스
- Compute Science
- 알고리즘
- CS50
- SSAFY 9기
- ssafy
- java
- Today
- Total
Joslynn의 하루
대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -18일차 노트 필기_Thread (스레드), synchronized 제한자, 동기화 블록, 람다식 표현 _220816 본문
대용량 웹서비스를 위한 MSA Full-Stack 개발자 양성 과정 -18일차 노트 필기_Thread (스레드), synchronized 제한자, 동기화 블록, 람다식 표현 _220816
Joslynn 2022. 8. 16. 18:20Thread
: 하나의 프로그램 안에서 여러 개의 작업을 동시에 일하는 것처럼 만들어주기 위해서 하나의 작업의 시간을 잘게 쪼개어(얇은 실타래처럼) 여러 개의 작업을 번갈아가면서 할 수 있도록 하는 것 == 멀티스레드
: CPU 자체는 동시에 여러 개의 일을 할 수 없지만, 작업시간을 잘게 쪼개 번갈아 작업함으로써 사용자 입장에서는 동시에 작업되는 것처럼 느껴짐
: 작업시간이 오래 걸리는 걸려 다른 일을 같이 해야하는 경우에만 사용
: 특정 스레드가 일을 많이 하는 것 같으면, 스레드 풀의 다른 스레드가 들어와서 일을 하는 등의 방식 // 해당 작업 순서 및 시간을 결정하는 것은 CPU
: main 자체도 하나의 스레드
: 단일 스레드는 하나의 작업이 끝나기 전까지는 다음 작업을 할 수 없음
≠멀티태스킹 = 하나의 응용프로그램 안에 여러 개의 프로그램이 동시에 작업되는 것;
스레드를 만드는 법
: Thread 객체를 만든 후 오버라이딩한 run() 메소드를 안에 기능들을 넣어줌
**main Thread : 직접 호출하지 않음;(단일 스레드 방지)
:~.start() 스레드의 시작을 알리는 메소드
: 스레드 및 main 스레드가 Thread Pool에서 대기하고 있음
1) 상속 - extends
class A extends Thread{
@ovverride
public void run(){
// Thread로 동작해야 할 일을 작성
}
}
** 호출
A a = new A();
a.start(); // 스레드가 대기(준비) 상태가 된다.
**주의사항: run()을 직접 호출하면 thread로 동작을 못한다.(그냥 일반 메소드 호출하는 것; 순차적으로 )
2) 구현 - implements
class B implements Runnable{ // run() 메소드 하나만 존재
@override
public void run(){
// 스레드로 동작해야 할 일
}
}
class B는 Runnable 변수에 담을 수는 있지만 Thread 변수 안에 담을 수는 없음;
Runnable은 run 메소드를 재정의하기 위한 인터페이스
**호출
B b = new B();
Thread th = new Thread(b); // Runnable을 인수로 넣어줌;
th.start();
Thread 예시)
package ex0816.thread;
public class ThreadExam {
public static void main(String[] args) {
System.out.println("***메인 시작합니다.***");
NumberThread th1 = new NumberThread("첫 번째 스레드");
NumberThread th2 = new NumberThread("두 번째 스레드");
AlphaThread alpha = new AlphaThread();
Thread th3 = new Thread(alpha, "세 번째 스레드");
// 우선순위
th1.setPriority(Thread.MAX_PRIORITY);
th2.setPriority(Thread.MIN_PRIORITY);
th3.setPriority(Thread.NORM_PRIORITY);
// 스레드 작업 시작
th1.start();
th2.start();
th3.start();
try {
th1.join();
} catch (Exception e) {
e.printStackTrace();
}
// 특정한 Thread가 일을 다 마칠때까지 아래 문장을 대기(메인스레드가 대기)
System.out.println("총 합 = " + th1.sum);
System.out.println("***메인 끝 입니다.***");
}
}
/**
* 1~100까지 출력하는 기능 스레드
* */
class NumberThread extends Thread{
public NumberThread(String name){
super(name);
}
@Override
public void run() {
for (int i =0; i<=100; i++) {
System.out.println(super.getName()+ "=>"+ i);
}
System.out.println(super.getName()+"종료");
}
}
/**A~Z까지 출력하는 기능 Thread
* */
class AlphaThread implements Runnable{
@Override
public void run() {
Thread th = Thread.currentThread(); // 현재 running중인 thread 객체 반환
for (char ch ='A'; ch<='Z'; ch++) {
System.out.println(th.getName()+ "=>"+ ch);
}
System.out.println(th.getName()+"종료");
}
}
Thread 객체의 주요 메소드
1) join메소드
: 현재 실행중인 메소드를 강제로 lock(실행대기) 상태로 변환하고 join 메소드 대상 스레드를 실행 및 종료될때까지 대기하게 하는 메소드
참고 블로그
2) sleep 메소드
: 특정 스레드가 반복적으로 일을 너무 많이 하는 것을 방지하기 위해 스레드를 잠시 중지시키는 것
: 일정시간의 중지가 끝나면 대기(준비)상태로 간다. // 바로 실행으로 들어갈 수 없음
: 무한 루프 돌릴 때, 특히 많이 사용
: ex> 시계 // 프로그램이 꺼질 때까지 1초마다 일하면 됨, sleep 메소드를 통해 일하는 빈도 수 제어
: 해당 스레드가 잠들어있는 동안 다른 스레드가 제어권을 가져와서 일할 수 있음
: static 메소드로 Thread.로 접근 가능;
3) yield메소드
: 양보 (실행중 상태에서 대기상태로 이동)
: static 메소드로 Thread.로 접근 가능;
**중지, 대기상태의 차이: 대기상태는 우선순위가 높다고 생각되면 바로 실행으로 들어올 수 있음 // 이미 대기상태이므로;
↔ 중지는 해당 시간이 끝날때까지 바로 실행으로 들어갈 수는 없음 (대기상태로 들어감)
람다식 표현
@FunctionalInterface
: 현재 interface가 한 개의 abstract 메소드를 가지고 있다는 표현
: 람다식 표현을 사용할 수 있다는 뜻 (-> 기능 구현)
: 함수적 선언 == 소스는 간결해진다.
: 람다식 표현식은 @FunctionalInterface가 선언된 interface 안에 있는 메소드가 한 개만 존재하는 경우, 구현 클래스를 만들 필요 없이 바로 기능을 구현할 수 있도록 해주는 문법
**원래 코딩 스타일
class Test implements Runnable{
@override
public void run(){
// 기능 작성
}
}
** 람다식 표현
Runnable r = () -> { // Runnuble에 있는 인수가 없는 메소드
//기능 작성
}
동기화(synchronized)
멀티스레드의 단점
: 하나의 프로그램 내의 하나의 자원을 여러 스레드가 공유하다보면, 눈에 보이지 않는 데이터 손실이 일어날 수 있음
: 해결방법 → 동기화 블럭을 만든다 (synchronized)
: synchronized → 특정 스레드가 동기화 블럭 영역을 다 마칠때까지 다른 스레드는 대기상태
: ex) 임계 영역(critical section), lock을 잡고 있다라고 표현
: 만약 특정 스레드가 임계 영역에서 error로 인해 못 빠져나온다면 다른 스레드는 무한 대기에 빠짐 → Deadlock(교착 상태)
**Deadlock 해결 방법:
wait() 메소드: 특정 Thread를 중지 상태로 만듦
notify(): wait에 의해 중지 상태인 Thread를 대기 상태로 이동 (우선 순위가 높은 스레드)
notifyAll(): wait에 의해 중지 상태인 Thread를 대기 상태로 이동 (모든 스레드)
동기화 : 어느 메소드가 실행하는 동안 다른 메소드를 실행이 불가능하게 블락하는 것 말한다.
비동기화 : 어느 메소드를 실행하는 도중에도 다시 메소드를 실행이 가능하다.
동기화 방법
1) method 자체를 동기화
2) 원하는 작업 부분만 동기화 블럭