Thread

: 프로세스 내에서 실제 작업을 수행이란 의미


간단하게 예를 들자면 단일 프로세스의 프로그램에서 채팅 프로그램을 구현한다면 대화를 주고 받기가 되질 않습니다 그저 한방향으로 실행되어지고 끝이 날뿐입니다 그래서 나온것이 쓰레드 입니다 하나의 프로세스에서 독립적으로 역활을 수행하는 쓰레드가 존재 함으로 123 123 123의 반복된 결과만 나오는 것이 아니라 111 121 122 321... 등의 다양한 값을 얻을수 있는 다시말하자면 프로세서내의 여러가지 기능을 수행하는 독립적인 다중 쓰레드를 사용함으로서 다양하고 편리한 목적의(멀티) 프로그램을 구현 할수 있습니다


Thread를 사용하는 2가지예

1) 상속 : extends Thread

 -Thread 객체를 선언하여 사용합니다

 -구현은 run()을 이용합니다

 -실행 매소드는 run()이 아닌 start()입니다 


2) 인터페이스 : implement Runnable

 -구현은 run()을 이용합니다

 -start()를 사용하기 위해서는 Thread객체를 사용해야 합니다


기본적인예제1>쓰레드 기본

소스보기 : 3 5 9단이 무작위로 출력되는 구구단을 출력하는 프로그램을 작성합니다 2가지 방법으로 구현 

1)extends

public class ThreadEx01 extends Thread {

private int d;

public ThreadEx01(int d){

this.d = d;

}

public void run(){

for (int i = 1; i < 10; i++) {

System.out.println(d+"*"+i+"="+d*i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

System.out.println();

}

public static void main(String[] args) {

ThreadEx01 th = new ThreadEx01(5);

th.start();

ThreadEx01 th1 = new ThreadEx01(9);

th1.start();

ThreadEx01 th2 = new ThreadEx01(3);

th2.start();

}

}


2)implement

public class ThreadEx02 implements Runnable {

private int d;

public ThreadEx02(int d){

this.d = d;

}

public void run(){

for (int i = 1; i < 10; i++) {

System.out.println(d+"*"+i+"="+d*i);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

System.out.println();

}

public static void main(String[] args) {

ThreadEx02 th = new ThreadEx02(5);

Thread t = new Thread(th);

t.start();

ThreadEx02 th1 = new ThreadEx02(9);

Thread t1 = new Thread(th1);

t1.start();

ThreadEx02 th2 = new ThreadEx02(3);

Thread t2 = new Thread(th2);

t2.start();

}

}



기본적인 예제2>쓰레드 충돌

: 기본 적으로 쓰레드를 사용하게 되면 1 2 3 의 독립 적인 3개체가 서로 중복되는 상황이 발생합니다 예를 들어 10000번 수행하는 프로그램의 경우 ++증가를 할경우 3개체가 중복이 되지 않으면 30000이 나와야 정상이지만 29997 28787등의 중복으로 인하여 정상적인 값이 출력이 되지 않습니다


implement로 구현

class Increment{

int num = 0;

public synchronized 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 < 100; i++) {

for (int j = 0; j < 100; j++) {

inc.increment();

}

}

}

}

public 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());

}

}


정상적으로 30000이 출력됩니다


추가로 스레드로 구성된 프로그램에서 main문 안의 System.out.println 출력문은  스레드가 어느 위치에서 실행이 되던지 제일 처음 출력이 됩니다 하지만 지금 같은 예제의 경우는 제일 마지막 프로그램 종료 시점에서 출력을 해야됩니다 이러한 경우 try문안에 join을 사용하면 스레드를 모두 실행한후 다음으로 넘어가게 되니다

Posted by mantwo