본문으로 바로가기

스레드란?

코드의 여러 부분이 동시에 실행되는 구조를 만들수 있다. 이러한 각각의 처리 흐름을 (thread)라고 부른다. 



스레드 기동시키기

 class Car extends Thread Thread 클래스 확장

{

public void run() run() 메소드를 반드시 정의해야 한다.

{

다른 스레드가 수행할 작업;
. . .

}

}

Thread -- Car 클래스


class Car extends Thread

{

private String name;

public Car(String nm)

{

name = nm;

}

public void run()

{

for(int i=0; i<5; i++)

{

System.out.println(name +"가 동작되고 있습니다.");

}

}

}


public class Sample1 {


public static void main(String[] args) {

// TODO Auto-generated method stub

Car car1 = new Car("1호차"); Thread 클래스의 서브 클래스 객체를 생성한다.

car1.start(); 새로운 스레드를 기동시킨다. Car클래스r가 Thread클래스로부터 상속받은 메소드

for(int i =0 ; i<5; i++)

{

System.out.println("main () 메소드 실행중입니다.");

}

}


}

실행결과


main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.




car1.start();를 출력하게 되면 새로운 스레드를 기동시키고 그 스레드는 가장 먼저 run()메소드를 실행시킬 것이라는 메커니즘에 따라 작동하게 된다. 그래서 1호차가 동작하고 있습니다라고 반복하고 있다.


한편, 새로운 스레드를 기동시킨 main()메소드 또한 별도의 작업을 계속 수행한다. 이 main()메소드는 'main()메소드 실행중입니다.란는 문구는 반복해서 출력한다.'


이 두개 처리 실행 순서는 정해져 있지 않는다. 사용 환경에 따라 출력 순서가 달라질 수 있다. 





여러개의 스레드 기동시키기


Sample1과 동일한 코드를 사용

class Car extends Thread

{

private String name;

public Car(String nm)

{

name = nm;

}

public void run()

{

for(int i=0; i<5; i++)

{

System.out.println(name +"가 동작되고 있습니다.");

}

}

}


public class Sample2 {


public static void main(String[] args) {

// TODO Auto-generated method stub

Car car1 = new Car("1호차");

car1.start();

Car car2 = new Car("2호차");

car2.start();

for(int i =0 ; i<5; i++)

{

System.out.println("main () 메소드 실행중입니다.");

}

}


}

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

1호차가 동작되고 있습니다.

2호차가 동작되고 있습니다.

2호차가 동작되고 있습니다.

2호차가 동작되고 있습니다.

2호차가 동작되고 있습니다.

2호차가 동작되고 있습니다.

새롭게 2호차 라는 객체를 new 사용하여 생성했다. 이 객체 또한 start()메소드를 호출시켜 준다. 그러면 스레드에 기동하게 된다. 

따라서 이 객체 안의 run()메소드가 실행된다. 2개였던 처리 흐름이 1개 증가하여 총 3개가 됨을 확인할 수 있었다. 이처럼 스레드는 여러 개 가동시킬 수 있다. 




스레드 상태 일시 정지시키기


Thread 클래스로부터 상속받은 메소드를 사용하면 스레드를 조작할 수 있다. 

그 예로, Thread 클래스의 sleep()메소드를 사용할 수 있다. 이 메소드를 사용하면

이미 가동중인 스레드를 일시적으로 정지가능하다. 


class Car extends Thread

{

private String name;

public Car(String nm)

{

name = nm;

}

public void run()

{

for(int i=0; i<5; i++)

{

try {

sleep(1000);

System.out.println(name +"가 동작하고 있습니다.");

}

catch(InterruptedException e)

{

}

}

}

}

public class Sample3 {


public static void main(String[] args) {

// TODO Auto-generated method stub

Car car1 = new Car("1호차");

car1.start();

for(int i =0 ; i<5; i++)

{

System.out.println("main () 메소드 실행중입니다.");

}

}


}


실행화면


main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.



실행시켜 보면 1호차가 동작하고 있습니다. 라는 문구가 1초의 간격을 두고 출력됨을 알 수 있었다. 스레드가 sleep()메소드를 실행시키면

()안에 지정된 밀리세컨드 동안 스레드를 일시 정지시키기 때문이다. 


다음 코드를 작성해 보자

class Car extends Thread

{

private String name;

public Car(String nm)

{

name = nm;

}

public void run()

{

for(int i=0; i<5; i++)

{

System.out.println(name +"가 동작하고 있습니다.");

}

}

}

public class Sample4 {


public static void main(String[] args) {

// TODO Auto-generated method stub

Car car1 = new Car("1호차");

car1.start();

for(int i =0 ; i<5; i++)

{

try {

Thread.sleep(1000);

System.out.println("main () 메소드 실행중입니다.");

}

catch(InterruptedException e) {

}

}

}

}





1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.

main () 메소드 실행중입니다.


이번에는 main()메소드의 문구가 1초간격으로 출력된다. sleep()메소드는 Thread 클래스의 메소드이다.




스레드 종료를 기다리기

다른 스레드의 종료를 기다리게 만들고 다시 동작하는 것 또한 가능하다. 그러한 처리가 필요한 경우 join()메소드를 사용한다. 


class Car extends Thread

{

private String name;

public Car(String nm)

{

name = nm;

}

public void run()

{

for(int i=0; i<5; i++)

{

System.out.println(name +"가 동작하고 있습니다.");

}

}

}

public class Sample5 {


public static void main(String[] args) {

// TODO Auto-generated method stub

Car car1 = new Car("1호차");

car1.start();

try {

car1.join();

}

catch(InterruptedException e) {

}

System.out.println("main () 메소드 실행중입니다.");

}

}



1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

1호차가 동작하고 있습니다.

main () 메소드 실행중입니다.  다른 스레드의 종료 후 출력된다. 


'프로그래밍 > java' 카테고리의 다른 글

동기화  (1036) 2017.09.15
쓰레드 생성,동기화  (1202) 2017.09.14
예외 및 입출력 처리  (1216) 2017.09.11
대규모 프로그램사용(파일분할, 패키지, 임포트)  (1197) 2017.09.08
인터페이스, 다중상속  (1218) 2017.09.04