환영합니다. Java 스레드 예제에 오신 것을 환영합니다. 프로세스와 스레드는 두 가지 기본 실행 단위입니다. 동시성 프로그래밍은 주로 Java 스레드에 관심이 있습니다.
프로세스
A process is a self contained execution environment and it can be seen as a program or application. However a program itself contains multiple processes inside it. Java runtime environment runs as a single process which contains different classes and programs as processes.
스레드
스레드는 경량 프로세스라고도 할 수 있습니다. 스레드를 생성하려면 더 적은 리소스가 필요하며 프로세스 내에서 존재하며, 스레드는 프로세스 리소스를 공유합니다.
Java 스레드 예제
모든 Java 애플리케이션은 적어도 하나의 스레드 – 주 스레드를 가지고 있습니다. 메모리 관리, 시스템 관리, 시그널 처리 등과 같은 많은 다른 Java 스레드가 백그라운드에서 실행되지만, 응용 프로그램 관점에서는 주 스레드가 첫 번째 Java 스레드이며 여기서 여러 스레드를 생성할 수 있습니다. 다중 스레딩은 하나의 프로그램에서 두 개 이상의 스레드가 동시에 실행되는 것을 의미합니다. 컴퓨터 단일 코어 프로세서는 한 번에 하나의 스레드만 실행할 수 있으며 타임 슬라이싱은 다른 프로세스와 스레드 간에 프로세서 시간을 공유하는 운영 체제 기능입니다.
Java 스레드의 장점
- Java 스레드는 프로세스에 비해 가볍습니다. 스레드를 생성하는 데 시간과 자원이 적게 필요합니다.
- 스레드는 부모 프로세스의 데이터와 코드를 공유합니다.
- 스레드 간의 컨텍스트 전환 비용은 일반적으로 프로세스 간의 전환 비용보다 적습니다.
- 스레드 간의 상호 통신은 프로세스 간의 통신보다 비교적 쉽습니다.
Java는 스레드를 프로그래밍적으로 생성하는 두 가지 방법을 제공합니다.
- java.lang.Runnable 인터페이스를 구현하는 것.
- java.lang.Thread 클래스를 확장하는 것.
Java 스레드 예제 – Runnable 인터페이스 구현
클래스를 실행 가능하게 만들려면 java.lang.Runnable 인터페이스를 구현하고 public void run()
메서드에 구현을 제공할 수 있습니다. 이 클래스를 스레드로 사용하려면 이 실행 가능한 클래스의 객체를 전달하여 Thread 객체를 만들고 start()
메서드를 호출하여 run()
메서드를 별도의 스레드에서 실행해야 합니다. 여기에는 Runnable 인터페이스를 구현한 Java 스레드 예제가 있습니다.
package com.journaldev.threads;
public class HeavyWorkRunnable implements Runnable {
@Override
public void run() {
System.out.println("Doing heavy processing - START "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
//데이터베이스 연결 가져오기, 사용되지 않는 데이터 삭제
doDBProcessing();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Doing heavy processing - END "+Thread.currentThread().getName());
}
private void doDBProcessing() throws InterruptedException {
Thread.sleep(5000);
}
}
Java 스레드 예제 – Thread 클래스 확장
우리는 java.lang.Thread 클래스를 확장하여 자체 Java 스레드 클래스를 만들고 run()
메서드를 재정의할 수 있습니다. 그런 다음 이를 객체로 만들고 start()
메서드를 호출하여 사용자 지정 Java 스레드 클래스 실행 메서드를 실행할 수 있습니다. 여기에는 Thread 클래스를 확장하는 간단한 Java 스레드 예제가 있습니다.
package com.journaldev.threads;
public class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
@Override
public void run() {
System.out.println("MyThread - START "+Thread.currentThread().getName());
try {
Thread.sleep(1000);
//데이터베이스 연결 가져오기, 사용되지 않는 데이터 삭제
doDBProcessing();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("MyThread - END "+Thread.currentThread().getName());
}
private void doDBProcessing() throws InterruptedException {
Thread.sleep(5000);
}
}
여기에는 Java 스레드를 만들고 실행하는 방법을 보여주는 테스트 프로그램이 있습니다.
package com.journaldev.threads;
public class ThreadRunExample {
public static void main(String[] args){
Thread t1 = new Thread(new HeavyWorkRunnable(), "t1");
Thread t2 = new Thread(new HeavyWorkRunnable(), "t2");
System.out.println("Starting Runnable threads");
t1.start();
t2.start();
System.out.println("Runnable Threads has been started");
Thread t3 = new MyThread("t3");
Thread t4 = new MyThread("t4");
System.out.println("Starting MyThreads");
t3.start();
t4.start();
System.out.println("MyThreads has been started");
}
}
위의 Java 스레드 예제 프로그램의 출력은:
Starting Runnable threads
Runnable Threads has been started
Doing heavy processing - START t1
Doing heavy processing - START t2
Starting MyThreads
MyThread - START Thread-0
MyThreads has been started
MyThread - START Thread-1
Doing heavy processing - END t2
MyThread - END Thread-1
MyThread - END Thread-0
Doing heavy processing - END t1
한 번 스레드를 시작하면 실행은 OS에서의 시간 분할 구현에 따라 달려 있으며 우리는 그 실행을 제어할 수 없습니다. 그러나 스레드 우선순위를 설정할 수 있지만 높은 우선순위 스레드가 먼저 실행될 것을 보장하지는 않습니다. 위의 프로그램을 여러 번 실행하면 스레드 시작과 종료에 어떤 패턴도 없음을 알 수 있습니다.
Runnable vs Thread
클래스가 Thread로 실행되는 것 이외에 추가 기능을 제공한다면, Runnable 인터페이스를 구현하여 Thread로 실행하는 방법을 제공해야 합니다. 클래스의 목표가 Thread로만 실행되는 것이라면 Thread 클래스를 확장할 수 있습니다. Runnable을 구현하는 것이 선호되는 이유는 Java가 여러 인터페이스를 구현할 수 있기 때문입니다. Thread 클래스를 확장하면 다른 클래스를 확장할 수 없습니다. 팁: 스레드가 값을 반환하지 않는다는 것을 알았을 것입니다. 그러나 스레드가 처리를 수행한 다음 결과를 클라이언트 프로그램에 반환하려면 Java Callable Future를 확인하세요. 업데이트: Java 8부터 Runnable은 함수형 인터페이스이며 람다 표현식을 사용하여 구현할 수 있습니다. 익명 클래스를 사용하는 대신 더 자세한 내용은 Java 8 함수형 인터페이스를 확인하세요.
Source:
https://www.digitalocean.com/community/tutorials/java-thread-example