개요 목적
하나의 프로세스에서 여러가지 일을 처리해주는 Thread를 자바 Runnable 인터페이스로 구현하는 방법에 대해서 알아본다.
Thread에 대한 자세한 이해는 아래 블로그 글에서 확인할 수 있다.
그리고 하나의 공유 자원을 여러 쓰레드에서 동시에 접근하여 생기는 동기화 문제를 방지하는 Synchronized 메소드에 대해서도 알아본다.
Runnable으로 Thread 구현하기
Runnable 인터페이스를 구현하여 Thread 동작을 하는 class를 만들 수 있다.
//Runnable 인터페이스를 상속받아서
//Thread 구현 동작을 run() 메소드 안에 작성한다.
public class RunnableThread implements Runnable{
@Override
public void run() {
System.out.println(LocalTime.now() + " Thread is started");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(LocalTime.now() + " Thread is exiting");
}
}
<실행 하기>
public class Main {
public static void main(String[] args) throws InterruptedException {
RunnableThread runnableThread = new RunnableThread();
//Thread 클래스 생성자에 내가 만든
//Runnable 구현 클래스를 생성자에 입력하여 Thread를 만든다.
Thread thread = new Thread(runnableThread);
//system.out.println은 내가 만든 스레드가 아닌
//메인 스레드이다. 즉 하나의 프로세스에서
//메인 스레드와 내가 만든 스레드가 동시에 작동되는 것을 확인할 수 있다.
System.out.println(LocalTime.now() + " Starting the thread");
//내가만든 Thread 시작
thread.start();
System.out.println(LocalTime.now() + " Waiting the thread()");
thread.join();
System.out.println(LocalTime.now() + " alive: " + thread.isAlive());
}
}
14:42:11.288475400 Starting the thread
14:42:11.303132400 Waiting the thread()
14:42:11.303132400 Thread is started
14:42:14.304954400 Thread is exiting
14:42:14.304954400 alive: false
thread.join()을 호출하면 MyThread가 종료될 때까지 main 스레드에서 기다려준다.
thread.join() 메소드가 없었으면, System.out.println(LocalTime.now() + " Thread is exiting"); 가 실행되지 못하고, 메인 스레드가 종료된다.
synchronized 사용하여 동시성 문제 해결
synchronized를 사용하여 하나의 스레드가 조작하고 있는 공유 자원을 다른 스레드가 조작하지 못하도록 Critical Section을 지정할 수 있다.
public class SynchronizedRunnable implements Runnable {
public int num1 = 0;
public int num2 = 0;
@Override
public void run() {
for (int i = 0; i < 1000000; i++) {
num1++;
//num2의 값에 접근할 때는
//하나의 쓰레드만 접근할 수 있다.
synchronized (this) {
num2++;
}
}
}
}
<사용 결과>
public class Main {
public static void main(String[] args) throws InterruptedException {
SynchronizedRunnable critical = new SynchronizedRunnable();
Thread t1 = new Thread(critical);
Thread t2 = new Thread(critical);
Thread t3 = new Thread(critical);
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println(critical.num1);
System.out.println(critical.num2);
}
}
num1= 2972276
num2= 3000000
num1은 세 스레드가 동시에 +1을 작업을 하여, 동기화 문제가 발생했다.
num2를 +1할 때는 한번에 하나의 스레드만 접속하여 올바른 계산 값이 나왔다.
'Web Sever 개발과 CS 기초 > 자바' 카테고리의 다른 글
Java Chatiing Server 만들기 (0) | 2023.05.05 |
---|---|
JavaBean 요구 조건과 Property (0) | 2022.10.01 |
ThreadLocal, Atomic 이해와 CAS 원리 (1) | 2022.09.30 |
Concurrent List, Concurrent HashMap 쉽게 이해하기 (0) | 2022.09.30 |
동시성 문제에 대한 이해와 Java의 Lock 객체 종류 (0) | 2022.09.30 |