자바는 멀티스레드 환경에서 동시성을 구현할 수 있는 강력한 기능을 제공합니다. 동시성은 여러 스레드가 동시에 실행되는 상황을 의미하며, 이를 통해 프로그램의 성능과 응답성을 향상시킬 수 있습니다. 이번 포스트에서는 자바에서 동시성을 구현하는 다양한 방법에 대해 알아보겠습니다.
1. Thread 클래스 사용하기
가장 기본적인 방법은 Thread
클래스를 직접 상속받아 스레드를 구현하는 것입니다. 아래는 간단한 예제입니다.
public class MyThread extends Thread {
public void run() {
// 스레드가 실행할 로직 작성
}
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
Thread
클래스는 run()
메서드를 오버라이딩하여 스레드가 실행할 로직을 구현합니다. start()
메서드를 호출하여 스레드를 시작할 수 있습니다.
2. Runnable 인터페이스 사용하기
Thread
클래스를 상속받는 대신에 Runnable
인터페이스를 구현하여 스레드를 생성할 수도 있습니다. 아래는 예제입니다.
public class MyRunnable implements Runnable {
public void run() {
// 스레드가 실행할 로직 작성
}
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start();
}
}
Runnable
인터페이스는 run()
메서드만을 가지고 있으므로, 스레드가 실행할 로직을 구현하는 것에 집중할 수 있습니다.
3. Executor 프레임워크 사용하기
자바는 java.util.concurrent
패키지를 통해 Executor 프레임워크를 제공하여 스레드를 관리하고 작업을 스케줄링할 수 있습니다. 아래는 예제입니다.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class MyTask implements Runnable {
public void run() {
// 작업 로직 작성
}
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 100; i++) {
executor.execute(new MyTask());
}
executor.shutdown();
}
}
ExecutorService
인터페이스를 사용하여 스레드 풀을 생성하고, execute()
메서드를 호출하여 작업을 스레드에게 할당합니다.
4. 동기화 메커니즘 사용하기
여러 스레드가 공유 데이터에 동시에 접근할 때 동기화 문제가 발생할 수 있습니다. 자바는 synchronized
키워드를 통해 동기화를 지원합니다. 아래는 예제입니다.
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
SynchronizedExample example = new SynchronizedExample();
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
executor.execute(() -> {
example.increment();
});
}
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
System.out.println("Count: " + example.getCount());
}
}
increment()
메서드에 synchronized
키워드를 사용하여 동기화를 적용하였습니다. 이를 통해 여러 스레드가 각각 increment()
메서드를 호출하더라도 안전하게 count 변수를 증가시킬 수 있게 됩니다.
결론
자바에서 동시성을 구현하는 방법에 대해 알아보았습니다. Thread
클래스나 Runnable
인터페이스를 사용하여 스레드를 직접 구현하거나, Executor 프레임워크를 사용하여 스레드를 관리하고 작업을 스케줄링할 수 있습니다. 또한 동기화 메커니즘을 통해 여러 스레드가 공유 데이터에 안전하게 접근할 수 있습니다. 동시성을 적절하게 활용하여 프로그램의 성능과 응답성을 개선할 수 있도록 노력해야 합니다.
참고 자료
- Java Concurrency Tutorial
- Goetz, Brian, et al. Java Concurrency in Practice. Addison-Wesley, 2006.