본문 바로가기

Java/본격 Java 스레드

[Java] 우선순위 스레드(Priority Thread)

이중 스레드에서 우선순위를 정해서 실행할 수 있을까?

.

.

class MessageThread extends Thread{
	String message;
	public MessageThread(String str, int prio){
		message = str;
		setPriority(prio);
		// 받아온 우선 순위를 현 인스턴스(스레드)에 지정
	}
	public void run(){
		for (int i = 0 ; i < 10 ; i++ ){
			System.out.println(message + "(" + getPriority() + ")");
			// getPriority() : 현재 동작중인 스레드의 우선순위 리턴
		}
	}
}

class  PriorityTest{
	public static void main(String[] args) 
	{
		MessageThread tr1 = new MessageThread("1st", Thread.MAX_PRIORITY);
		MessageThread tr2 = new MessageThread("2nd", Thread.NORM_PRIORITY);
		MessageThread tr3 = new MessageThread("3rd", Thread.MIN_PRIORITY);

		tr1.start();
		tr2.start();
		tr3.start();
		// 우선 순위를 각 스레드별로 지정할 수 있어 실행순서를 어느정도는 제어함
		// 단, 실행순서가 반드시 우선 순위에 맞춰 실행되지는 않음
		// 스레드에서는 순서가 필요한 작업을 하면 안됨
	}
}

.

.

thread 클래스에 각 스레드 별로 실행순서를 제어할 수는 있지만

반드시 우선순위에 맞춰 작동하지 않는걸 볼 수 있다.

그러면 어떤 방법을 이용해야할까?

.

.

그러면 synchronized를 이용하면된다.

.

.

비교하기 위해서 sychronized를 사용하지 않은 스레드를 구현해본다.

class Increment{
	int num = 0;
	public void increment(){ num++; }
	public int getNum(){ return num; }
}

class IncThread extends Thread{
	Increment inc;
	public IncThread(Increment inc){ this.inc = inc; }
	public void run(){
		for (int i = 0 ; i < 10000 ; i++ ){
			for (int j = 0 ; j < 10000 ; j++ ){
				inc.increment();
			}
		}
	}
}

class  ThreadSyncError {
	public static void main(String[] args) {
		Increment inc = new Increment();
		IncThread it1 = new IncThread(inc);
		IncThread it2 = new IncThread(inc);
		IncThread it3 = new IncThread(inc);

		it1.start();
		it2.start();
		it3.start();
		try{
			it1.join();
			it2.join();
			it3.join();
		}catch (InterruptedException e){
			e.printStackTrace();
		}
		System.out.println(inc.getNum());
	}
}

.

.

그러면 3개의 스레드가 실행되도록 코드를 짰지만 3억번 실행될 것이 랜덤으로 변하게 된다.

그래서 해결책으로 synchronized를 사용해보자

.

.

class Increment{
	int num = 0;
	public synchronized void increment(){ num++; }
	// synchronized : 특성 스레드가 작업하는 동안 다른 스레드가 접근하지 못하게 함
	// 보통은 메소드자체에 붙이지 않고 실제 작업하는 영역에만 붙여서 속도를 올림
	public int getNum(){ return num; }
}

class IncThread extends Thread{
	Increment inc;
	public IncThread(Increment inc){ this.inc = inc; }
	public void run(){
		for (int i = 0 ; i < 10000 ; i++ ){
			for (int j = 0 ; j < 10000 ; j++ ){
				inc.increment();
			}
		}
	}
}

class  ThreadSyncSuccess {
	public static void main(String[] args) {
		Increment inc = new Increment();
		IncThread it1 = new IncThread(inc);
		IncThread it2 = new IncThread(inc);
		IncThread it3 = new IncThread(inc);

		it1.start();
		it2.start();
		it3.start();
		try{
			it1.join();
			it2.join();
			it3.join();
		}catch (InterruptedException e){
			e.printStackTrace();
		}
		System.out.println(inc.getNum());
	}
}

.

.

이러면 순서대로 실행되는걸 볼 수 있다

그냥 스레드를 사용한다면 각각의 스레드가 실행될 때 서로 순서상관없이 실행되지만

synchronized를 사용하면 하나의 스레드가 실행될 때 다른 스레드들이 기다리도록할 수 있다.

728x90
반응형

'Java > 본격 Java 스레드' 카테고리의 다른 글

[Java] synchronized thread 실습  (0) 2020.07.02
[Java] Runnable 스레드(Runnable thread)  (0) 2020.07.02
[Java] 스레드(Thread)  (0) 2020.07.02