15. 스레드

15-1. 스레드의 기본

스레드의 원리

Java : 하나의 코드가, “여러 처리 흐름”을 가질 수 있도록 지원함

  • 각각의 처리 흐름 = “스레드”

스레드를 늘리는 행위 = “스레드를 기동시킨다”

  • 효율적인 처리가 가능함


스레드 기동시키기

우선, Thread 클래스를 확장한 클래스를 만들어야!

반드시 run() 메소드를 정의해야함

class Car extends Thread
{
    public void run()
    {
        // 다른 스레드가 수행할 작업
    }
}


Example

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+"가 동작중")
        }
    }
}

class Sample
{
    public static void main(String[] args)
    {
        // thread의 서브 클래스 객체 생성
        Car car1=new Car("1호차");
        
        // 새로운 thread 기동시키기
        car1.start();
        
        for(int i=0;i<5;i++){
            System.out.println("main() 메소드 실행 중");
        }
    }
}

결과

main() 메소드 실행 중
main() 메소드 실행 중
1호차가 동작중
main() 메소드 실행 중
main() 메소드 실행 중
1호차가 동작중
main() 메소드 실행 중
1호차가 동작중
...
  • 뭐가 먼저 처리될지는 컴바컴


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

class Sample
{
    public static void main(String[] args)
    {
        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() 메소드 실행 중")
        }
    }
}
  • 처리흐름이 2개에서 3개로 늘어남!


15-2. 스레드의 상태 변화시키기

스레드 일시정지 ( 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){}
        }
    }
}

class Sample
{
    public static void main(String[] args)
    {
        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호차가 동작중


이번엔, main() 메소드가 1초 간격으로 출력되도록!

class Car extends Thread
{
    private String name;
    public Car(String nm)
    {
        name=nm;
    }
    public void run()
    {
        for(int i=0; i<5; i++){
            try{
                System.out.println(name+"가 동작중"); 
            }
            catch(InterruptedException e){}
        }
    }
}

class Sample
{
    public static void main(String[] args)
    {
        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){}
        }
    }
}


스레드 종료를 기다리기

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+"가 동작중")
        }
    }
}

class Sample
{
    public static void main(String[] args)
    {
        Car car1=new Car("1호차");
        car1.start();
        
        try{
            car1.join();
        }
        catch(InterruptedException e){}
        
        System.out.println("main() 메소드 실행 중");
    }
}

결과

1호차가 동작중
1호차가 동작중
1호차가 동작중
1호차가 동작중
1호차가 동작중
main() 메소드 실행 중


15-3. 스레드의 생성 방법

스레드를 생성하는 또 다른 방법

Thread 클래스를 상속 받은 클래스가…. 기존에 이미 다른 클래스 상속받았을 경우?

  • Runnable 인터페이스를 사용!
  • Thread 클래스를 확장하는 것이 아니라, Runnable 인터페이스를 구현!
class Car extends Vehicle implements Runnable


Example

// Runnable 인터페이스 구현
class Car implements Runnable
{
    private String name;
    public Car(String nm)
    {
        name=nm;
    }
    
    // Run 메소드 정의
    public void run()
    {
        for(int i=0;i<5;i++){
            System.out.println(name+"가 동작 중")
        }
    }
}

class Sample
{
    public static void main(String[] args)
    {
        Car car1=new Car("1호차");
        // Thread 클래스의 객체 생성
        Thread th1 = new Thread(car1);
        // Thread 기동시키기
        th1.start();
        
        for(int i=0;i<5;i++){
            System.out.println("main() 메소드 실행 중");
        }
    }
}


15-4. 동기화

스레드 여러개 사용 시 주의점!

동일 필드에, 여러 스레드가 동시에 접근하면 안되는 경우!

public synchronized void add(int a)
{
	...
}

Tags:

Categories:

Updated: