이중 스레드에서 우선순위를 정해서 실행할 수 있을까?
.
.
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 |