본문 바로가기

Java/Java 기초

쓰레드(Thread)의 사용

쓰레드(Thread)는 하나의 프로세스 내에서 여러 작업을 동시에 실행할 때 사용한다. 프로세스 내에서 쓰레드를 사용하면 다양한 작업을 동시에 진행할 수 있고 작업중에 얻게된 데이터를 공유할 수 있다는 이점과 여러개 프로세스를 사용할 경우 각 프로세스마다 메모리가 할당되는데 단일 프로세스 내의 쓰레드는 같은 메모리 공간을 공유한다는 이점이 있다. 쓰레드를 사용하는 대표적 사례로는 게임을 들 수 있을 것이다. 플레이어와 적의 움직임이 동시적으로 일어나야하지만 둘사이의 어떠한 연관성도 없기 때문에 둘의 움직임은 한 프로세스 내에서도 독립적으로 작동해야한다는 것을 알 수 있다.


쓰레드는 기본적으로 Thread Class를 상속받아 구현하며, 실제 쓰레드로 작동할 run() 함수를 start() 함수로 작동시키는 구조로 되어있다.


아래의 코드는 점프 투 자바를 참조하여 작성한 코드이다.

https://wikidocs.net/230


public class ThreadTest1 extends Thread {
	private int seq;

	public ThreadTest1(int seq) {
		this.seq = seq;
	}

	public static void main(String[] args) {
		for (int i = 1; i <= 10; i++) {
			ThreadTest1 tt1 = new ThreadTest1(i);
			tt1.start();
		}
		System.out.println("main end.");
	}

	public void run() {
		System.out.println(this.seq + " thread start.");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {

		}
		System.out.println(this.seq + " thread end.");
	}
}


이 코드를 돌려보면 결과값이 시작은 비교적 순차적으로 나오는데 반해서 종료되는 순서는 제각각인 것을 알 수 있다. 쓰레드들이 거의 동시에 돌게되고 시작출력 + 1초의 대기 시간 + 종료출력의 작업이 먼저 끝나는 쓰레드들이 먼저 종료되기 때문이다. 특이한 것은 시작이 다 마치지도 않았는데 main() 함수가 끝나버렸다는 사실이다. 이를 해결하기 위해서는 join() 함수를 사용해야한다.


import java.util.ArrayList;

public class ThreadTest2 extends Thread {
	private int seq;

	public ThreadTest2(int seq) {
		this.seq = seq;
	}

	public static void main(String[] args) {
		ArrayList<Thread> threads = new ArrayList<Thread>();

		for (int i = 0; i < 10; i++) {
			Thread t = new ThreadTest2(i + 1);
			t.start();
			threads.add(t);
		}

		for (int i = 0; i < 10; i++) {
			Thread t = threads.get(i);
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("main end.");
	}
	
	public void run() {
		System.out.println(this.seq + " thread start.");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {

		}
		System.out.println(this.seq + " thread end.");
	}
}


마지막으로 많이 사용하는 Runnable 인터페이스를 implements 하여 구현하는 Thread이다. 기존과 다른 점은 Thread를 상속받은 것이 아니므로 만들어진 ThreadTest 객체를 바로 Thread로 받아 배열에 입력하는 것이 아니라 Thread 생성자를 이용하여 객체를 넘겨야 한다는 것이다. 


import java.util.ArrayList;

public class ThreadTest3 implements Runnable {
	private int seq;

	public ThreadTest3(int seq) {
		this.seq = seq;
	}

	public static void main(String[] args) {
		ArrayList<Thread> threads = new ArrayList<Thread>();

		for (int i = 0; i < 10; i++) {
			Thread t = new Thread(new ThreadTest3(i + 1));
			t.start();
			threads.add(t);
		}

		for (int i = 0; i < 10; i++) {
			Thread t = threads.get(i);
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("main end.");
	}

	public void run() {
		System.out.println(this.seq + " thread start.");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(this.seq + " thread end.");
	}
}


'Java > Java 기초' 카테고리의 다른 글

Java Stack 구현  (0) 2018.05.24
XSS(Cross-site scripting) 특수문자 치환  (0) 2018.05.10
Arrays.binarySearch() 사용  (0) 2017.12.29
접근제어자 public, protected, default, private  (0) 2017.12.23
스태틱(static)  (0) 2017.11.23