목차
Thread
Thread 추가로 만들어서 사용하기
Thread실행시 스레드 상태(Thread Status)
Thread
컴퓨터에서 다수의 사용자들을 동시에 처리할 수 있는 프로그램이 각각의 사용과 관련하여 가지고 있는 정보들.
스레드는 프로세스 내에서 실제로 작업을 수행하는 단위이다. 모든 자바 프로그램은 메인 스레드에서 시작되며, 사용자는 추가적인 스레드를 생성할 수 있다. 각 스레드는 독립적으로 실행되며, 자신만의 호출 스택을 가진다. (각 스레드의 스택 영역은 서로 격리되어 있다.) 프로세스 내의 모든 스레드는 같은 Heap 메모리 공간과 다른 자원을 공유할 수 있다.
public class MyThread extends Thread{
// 메인 함수 - 메인 스레드(메인 작업자)
// 기본적으로 메인 작업자를 하나 가지고 있다. = 메인 스레드
// 필요하면 스레드를 더 추가할 수도 있다.
public static void main(String[] args){
System.out.println("스레드");
}
}
■ Process
저장되어 있는 프로그램이 실행되면 OS로부터 메모리를 할당받아 프로세스 상태가 된다.
하나의 프로세스는 하나 이상의 thread를 가지게 되고, 실제 작업을 수행하는 단위는 thread이다.
Thread 추가로 만들어서 사용하기
1. 첫 번째 방법 - Thread 클래스를 상속하여 만들 수 있다.
// 스레드 추가하는 방법
// 첫 번째 - 상속을 활용한다. Thread -> Runnable -> run()
public class MyThread extends Thread{
// 정의한 클래스에서 run() 메서드를 재정의할 수 있다.
// 스레드를 사용할 때 알아야 하는 필수 개념이며 이해가 되지 않아도 일단 외워야 한다.
// 스레드가 가지고 있는 메서드 start()를 호출시키면 약속으로
// run() 메서드가 호출되어 동작하게 만들어져 있다.
@Override
public void run(){
// 동작시키고자 하는 일을 정의해서 코드를 설계할 수 있다.
// 반복문 200번 수행하는 코드
for(int i = 0; i < 200; i++){
System.out.println(i);
try{
Thread.sleep(500);
} catch(InterruptedException e){
e.printStackTrace();
}
} // end of for
} // end of run()
} // end of class
public class MyThreadMainTest{
public static void main(String[] args){
System.out.println(Thread.currentThread());
// 필요하면 추가 작업자를 사용할 수 있다.
MyThread th1 = new MyThread();
th1.start();
// start()메소드는 스레드 안에 있다.
// Thread 안에 있는 start()호출 --> run()메소드가 동작되도록 약속되어 있다.
// 필요하면 추가 작업자를 더 만들 수 있다.
MyThread th2 = new MyThread();
th2.start();
} // end of main
} // end of class
public class Worker extends Thread{
private String name;
public Worker(String name){
this.name = name;
}
// 약속된 부분인 run() 메서드를 정의하면 된다.
@Override
public void run(){
for(int i = 0; i < 50; i++){
System.out.println("worker : " + name + " : " + i);
try{
Thread.sleep(200);
} catch(InterruptedException e){
e.printStackTrace();
}
} // end of for
} // end of run()
} // end of class
public class WorkerMainTest{
// 메인 작업자 main thread
public static void main(String[] args){
System.out.println("--- start main thread ---");
System.out.println(Thread.currentThread());
// 작업자 하나 더 만들어 내기
Worker worker1 = new Worker("워커1"); // <-- 생성은 메인 스레드가 했다.
worker1.start(); // <-- 메인 스레드가 명령을 내렸고, worker1은 위임받은 일을 시작한다.
System.out.println("--- end main thread ---");
} // end of main
} // end of class
2. 두 번째 방법 - Runnable 인터페이스를 구현하여 만들 수 있다.
public class MyThread2 implements Runnable{
// Thread 클래스에서 start 메소드가 호출되면
// 동작하는 부분이라고 약속되어 있다.
@Override
public void run(){
int i = 0;
while(i < 10){
System.out.println("i : " + i);
i++;
try{
Thread.sleep(1000);
} catch(InterruptedException e){
e.printStackTrace();
}
} // end of while
} // end of run()
} // end of class
public class MyThread2MainTest{
public static void main(String[] args){
System.out.println("main start");
// MyThread2를 메모리에 올리고 그 안에 정의된 run()메서드를 호출하고 싶다.
// 힌트 --> Thread 문서에서 생성자 확인하기.
MyThread2 myThread2 = new MyThread2();
// 여기서 만약 myThread2.run();을 호출하면 이건 일반 메서드를 호출하는 것이다.
// 새로운 작업자를 생성해서 위임 시킬때는 Thread 안에 있는 start()메서드를 호출해야 한다.
// 결국 다른 작업자에게 일을 위임하려면 >>스레드<<에 start()를 호출해야 한다.
Thread thread1 = new Thread(myThread2);
thread1.start();
System.out.println("--- end main thread ---");
} // end of main
} // end of class
Thread 실행시 스레드 상태 (Thread Status)
멀티 스레딩 Multi-threading
자바에서 멀티 스레딩은 프로그램의 여러 부분이 동시에 실행되도록 하는 기술이다. 이를 통해 자원의 효율적 사용과 응용 프로그램의 반응성 향상을 달성할 수 있다. 멀티 스레딩은 하나의 프로세스 내에서 여러 개의 스레드를 생성하여 각 스레드가 작업을 수행하도록 함으로써 병렬 처리를 가능하게 한다.
정리
☞ 여러 스레드가 동시에 수행되는 프로그래밍, 여러 작업이 동시에 실행되는 효과
☞ 스레드는 각각 자신만의 작업 공간을 가진다. = call Stack
☞ 각 스레드 사이에서 공유하는 자원이 있을 수 있다. (자바에서는 static instance)
☞ 여러 스레드가 자원을 공유하여 작업이 수행되는 경우 서로 자원을 차지하려는 race condition이 발생할 수 있다.
☞ 이렇게 여러 스레드가 공유하는 자원 중 경쟁이 발생하는 부분을 critical section이라고 한다.
☞ critical section에 대한 동기화(일종의 순차적 수행)를 구현하지 않으면 오류가 발생할 수 있다.
멀티 스레딩 장점
☞ 자원을 효율적으로 사용 : CPU 사용률을 향상시키고 자원을 효율적으로 사용할 수 있다.
☞ 응용 프로그램의 반응성 향상 : 긴 작업을 처리하는 동안 사용자 인터페이스가 멈추지 않고 반응할 수 있다.
☞ 병렬 작업 : 여러 하드웨어 코어를 활용하여 작업을 병렬로 처리할 수 있어 실행 시간을 단축시킨다.
주의사항
멀티 스레딩 환경에서는 여러 스레드가 동일한 자원에 동시에 접근할 때 발생할 수 있는 문제들(예:경쟁상태, 교착상태)을 고려해야 한다. 이러한 문제를 해결하기 위해 자바는 동기화(synchronization) 메커니즘을 제공한다.
멀티 스레드 프로그래밍에서 동기화 (synchronization)
☞ 스레드 두 개가 같은 객체에 동시 접근하면 오류 발생
☞ 동기화는 임계영역에 접근한 경우 공유자원을 lock하여 다른 스레드가 접근 못하게 제어한다.
☞ 자바에서는 동기화 메서드(synchronization methods)나 동기화 블럭(synchronization block)을 사용한다.
해결방안
동기화 메서드
객체 메소드에 synchronization 키워드 사용 → 현재 이 메소드가 속해있는 객체에 lock을 건다.
동기화 블럭
현재 객체 또는 다른 객체를 lock로 만든다.
시나리오 코드
각 스레드가 공유하는 자원 만들어 보기 (sharedResource 상황을 구현해보자)
두 사람이 같은 계좌를 공유하고 있다. 계좌 잔액은 10만원이며, 한 사람은 1만원을 입금했고 한 사람은 5천원을 출금했다.
멀티 스레드 동기화를 사용하여 계좌 잔액 10만 5천원을 출력하시오.
'Java' 카테고리의 다른 글
바이트 기반 - 파일 입출력/Copy (0) | 2024.05.20 |
---|---|
I/O, 표준 입출력 (0) | 2024.05.20 |
Exception(예외처리) (0) | 2024.04.29 |
String, StringBuffer 클래스 (0) | 2024.04.29 |
Object 클래스 (0) | 2024.04.29 |