쓰레드를 알려면 먼저 프로세스에 대해서 알아야 하는데
일반적으로 프로그램을 "실행" 시켜서 동작하게 만들면 이것을 "프로세스"라고 한다.
다시 말해서, 우리가 실행시키는 하나의 프로그램은 하나의 프로세스로서 나타나게 된다.
(ex : 이클립스를 새 창으로 2개를 띄웠다면, 2개의 프로세스가 실행 중이라 말할 수가 있다.)
여러 프로그램을 실행시키는 것은 멀티 프로세스라고 한다
우리가 컴퓨터를 하는데 보통 워드 작업하면서 음악도 듣고,
간간이 카톡도 하듯이 여러 프로그램을 동시에 실행하는 것을 말한다
대표사진 삭제
사진 설명을 입력하세요.
프로세스는 프로그램을 수행하는 데 필요한 데이터와 메모리 등의 자원 그리고 쓰레드로 구성되어 있다.
쓰레드는 프로세스의 자원을 이용해서 실제로 작업을 수행하는 역할을 한다.
그래서 모든 프로세스에는 최소한 하나의 쓰레드가 존재한다
하지만 꼭 하나만 존재하지 않고, 쓰레드가 두 개 이상이면 이것을 멀티 스레드(Multi- Thread)라고 한다
프로세스 동작의 최소 단위.
하나의 프로세스 내부에서 독립적으로 실행되는 하나의 작업 단위를 말한다
한 프로세스에서 동작되는 여러 실행 흐름이라고도 말할 수 있다.
이 프로세스는 보통 하나의 루틴 즉, 프로그램 처리 경로를 가지고 있는데
보통 이 루틴은 직렬적이다.
그런데 자바 쓰레드를 이용하면 하나의 프로세스에서도 병렬적으로 처리,
즉 여러 개의 처리 루틴을 가질 수 있다. 단순 반복의 코드를 실행할 때도
여러 개의 쓰레드를 만들어서 분리 시킨 뒤 결과 데이터를 받아 합치면
그만큼 시간을 절약할 수 있다.
프로세스는 운영체제로부터 작업을 할당받는 작업의 단위이고,
스레드는 프로세스가 할당받은 자원을 이용하는 실행의 단위이다.
둘 이상의 스레드로 구성된 프로세스도 존재하는 데
이것을 멀티 스레드 프로세스라고 한다
▶ Multi Thread(멀티 스레드) 장점
1. 메모리 공유로 인한 시스템 자원 소모가 줄어듭니다.
2. 동시에 두 가지 이상의 활동을 하는 것이 가능해진다. 그래서 CPU에 사용률이 올라간다
3. 작업의 분리로 응답성 향상
▶ Multi Thread(멀티 스레드) 단점
1. 서로 자원을 소모하다가 충돌이 일어날 가능성이 존재한다.
2. 코딩이 난해해져 버그 생성 확률이 높아진다.
1. Thread 클래스를 상속받아 run() 메서드를 오버라이딩
=> 인스턴스 생성 후 start() 메서드를 호출하여 멀티쓰레딩 실행
2. Runnable 인터페이스를 구현하여 run() 메서드를 오버라이딩
=> start() 메서드가 존재하지 않으므로
Thread 클래스 생성자에 Runnable 인터페이스 구현 객체를 전달한 뒤
Thread 클래스를 통해 start() 메서드를 대신 호출하여 멀티쓰레딩 실행
- run() 메서드는 내부적으로 JVM에 의해 호출될 메서드
(사용자가 호출할 메서드는 start() 메서드로 메서드 내에서 run() 메서드 호출됨)
Thread 클래스를 상속받는 서브 클래스를 정의하는 방법을 살펴보자
Thread를 상속받고, run() 메서드를 오버라이딩해야 하고, 호출할 때는 start()로 메서드로 해야 한다.
publicstaticvoidmain(String[]args) {
MyThread mt1 = new MyThread("★ A 작업★", 1000000);
MyThread mt2 = new MyThread("※ B 작업※", 500000);
MyThread mt3 = new MyThread("◎ C 작업◎", 1000000);
mt1.start();
mt2.start();
mt3.start();
}}
class MyThread extends Thread {
String name;
int count;
public MyThread(String name, int count) {
super();
this.name = name;
this.count = count;
}
@Override
public void run() {
for(int i = 1; i <= count; i++) {
System.out.println(name + " : " + i);
}
}
}
2. Runnable 인터페이스를 구현하는 서브 클래스를 정의하는 방법
class A {}
기존에 다른 클래스를 상속받은 상태에서는 Thread 클래스를 상속받을 수 없으므로
Runnable 인터페이스를 상속받아 run() 메서드를 오버라이딩 한다!
run() 메서드 내부에 멀티쓰레딩으로 처리할 코드를 기술
=> 여기에 기술되는 코드들은 (다른 작업과 별개로 동시에 수행됨)
publicstaticvoidmain(String[]args) {
Threadt1=newThread(yt1); =>생성자에 Runnable 구현한 인스턴스를 전달 가능
Threadt2=newThread(yt2);
Threadt3=newThread(yt3);
t1.start();=> Thread 클래스의 start() 메서드를 호출
t2.start();
t3.start();;
}}
Runnable 인터페이스 내에 start() 메서드가 없을뿐더러
있다 하더라도 추상메서드이므로 호출이 불가능!!!!!!!!!!!!!!!
Thread 클래스의 인스턴스를 생성하고,
생성자에 Runnable 을 구현한 서브 클래스의 인스턴스를 전달하여
Thread 인스턴스에서 대신 start() 메서드를 호출해야 한다!
classA {}
class YourThread extends A implements Runnable {
String name;
int count;
public YourThread(String name, int count) {
super();
this.name = name;
this.count = count;
}
Runnable 인터페이스를 구현한 뒤 반드시 run() 메서드 오버라이딩 필수!
@Override
public void run() {
for(int i = 1; i <= count; i++) {
System.out.println(name + " : " + i);}}}
① NEW : 스레드가 생성되었지만 스레드가 아직 실행할 준비가 되지 않았음
② RUNNABLE : 스레드가 실행되고 있거나 실행 준비되어 스케줄링은 기다리는 상태
③ WAITING : 다른 스레드가 notify(), notifyAll()을 불러주기 기다리고 있는 상태(동기화)
④ TIMED_WAITING : 스레드가sleep(n)호출로 인해 n 미리 초 동안 잠을 자고 있는 상태
⑤ BLOCK : 스레드가 I/O 작업을 요청하면 자동으로 스레드를 BLOCK 상태로 만든다.
⑥ TERMINATED : 스레드가 종료한 상태
- 스레드 상태는 JVM에 의해 기록 관리된다.
스레드는 Thread 객체가 생성되면 생명 주기를 갖게 되는데 크게 5가지로 나누게 된다.
▶ New - 스레드가 만들어진 상태
▶ Runnable - 스레드 객체가 생성된 후에 start() 메서드를 호출하면 Runnable 상태로 이동하게 된다.
▶ Running - Runnable 상태에서 스레드 스케줄러에 의해 Running 상태로 이동하게 된다.
▶ Blocked - 스레드가 다른 특정한 이유로 Running 상태에서 Blocked 상태로 이동하게 된다.
▶ Dead - 스레드가 종료되면 그 스레드는 다시 시작할 수 없게 된다.
스레드 실행과 관련된 2가지 중요한 메서드는 바로start()와 run()이다
▶ start() 메서드 호출은 스레드의 run() 메서드가 호출될 수 있도록 준비하는 과정
NEW에서 RUNNABLE로 보낸다.
▶ run() 메서드는 스레드에서 수행할 작업을 정의하는 메서드
RUNNING 이 된다면 여기에 있는 이 메서드에 오버라이딩된 로직을 수행한다.
▶ yield() : (우선권이 동일한) 스레드에게 실행할 기회를 양보함.
이걸 실행하면 RUNNING 상태에서 RUNNABLE 상태로 바뀐다.
▶ sleep() : 현재 실행 중인 스레드를 주어진 시간 동안 TIMED_WAITING 상태로 빠트린다.
yield와 차이점은 주어진 시간이 있고 없는 것.
▶ join() : 다른 스레드와 협동 작업할 때 주로 쓴다. 호출되면 BLOCKED 상태가 되었다가,
기다리는 스레드의 작업이 끝나면 다시 RUNNABLE로 간다. 이해를 돕기 위해 사진과 간단한 코드를..
현재 실행 주인 스레드에 대한 각종 제어 수행 가능한데
sleep() 메서드를 호출하면 현재 실행 중인 쓰레드를 대어 풀에서 재운다
파라미터로 미리 초 단위 시간 설정이 가능하며,
시간이 만료되거나 interrupt() 메서드가 호출되면 대어 풀에서 Runnable로 이동한다
우선순위가 낮은 쓰게 그가 실행되지 못하는 상태(기아)를 방지하기 위해서
모든 스레드들을 일정 시간 동안 재운다(sleep)
스레드들은 별도의 스택에서 따로따로 동작하기 때문에 제어하기 쉽지 않다
스레드가 Runnable 상태에서 선택될 때 우선순위가 적용된다
예를 들어 메신저 채팅과 파일 전송 두 개의 작업이 스레드로 진행 중이라면
어떤 작업이 더 우선순위가 있을까?
파일전송은 잠시 멈춰도 불평이 생기지 않지만 채팅 메시지는 바로 전달되지 않으면 불만이 생긴다
이처럼 여러 스레드가 있을 때 먼저 실행되기 위해서는 우선순위가 높은 것이 좋다
우선순위는 스레드의 중요도에 따라 1~10까지 정수로 지정할 수 있다
(이때 10이 우선순위가 높은 것, 5는 보통)
스레드 우선순위는setPriority()와 getPriority() 메서드로 설정할 수 있다
하지만 우선순위가 높다고 언제가 그 스레드가 실행되는 것은 아니고
한번 시작했다고 해서 끝까지 동작하지도 않는다
멀티스레드에서 문제점이 바로 공유데이터 신뢰성에 문제가 생길 수도 있는데
이를 위해서 공유 데이터를 동기화 처리 해야 한다
멀티스레드 프로그래밍에서는 이 문제를 해결하기 위해
lock개념과 synchronized키워드를 사용한다
synchronized 메서드 또는 블록에 사용해 임계영역에서는 동시에
하나의 스레드만 사용할 수 있다
즉 공유구간에 대한 설정이다.
synchronized 키워드를 사용하면 동시에 접속 못하게 만들거다 라는 뜻
실제 코드를 통해 synchronized 구현한 모습을 보자
ㅣ읽느라 수고 많으셨어요~ㅣ
부족한 글을 읽어주셔서 감사드립니다
아직 부족한 게 많으니
틀린 곳이 있다면
조언의 말씀 꼭 부탁드립니다!!!!
[자바] 형식화 클래스_ SimpleDateFormat 클래스/날짜보기쉽게 만들어 주는 유용한 기능 (0) | 2020.08.22 |
---|---|
[자바] MessageFormat 클래스/연결하기/끼워넣기/배열에 사용하기 (0) | 2020.08.21 |
[자바]예외(Exception)처리_try catch fianlly 구문/ try with resource 구문 (0) | 2020.08.19 |
[자바] 패키지 종류(유틸리티, 입출력, 유저인터페이스GUI패키지)_Date,Random,Math (0) | 2020.08.18 |
[java]util.Date 클래스(자바의 시각과 날짜를 담는 클래스) (0) | 2020.08.16 |