스레드(thread)&멀티스레드&동기화-미완성

2020. 3. 17. 12:51자바 Java/자바 공부 java study

반응형

다중 스레딩(multi-threading)은 하나의 프로그램이 동시에 여러가지 작업을 할 수 있도록 하는 것. 

각각의 작업은 스레드 라고 불린다. (두개 이상의 스레드- 멀티 스레드) 

멀티 프로세스는 한번에 여러가지 프로그램을 실행시키는 것

멀티 스레드는 하나의 프로그램 안에서 여러개의 명령처리를 하는 것. 

 

프로세스:  자신망의 데이터를 가진다. 

스레드: 동일한 데이터를 공유한다. 

 

스레드는 어떠한 프로그램 내에서 특히 프로세스 내에서 실행되는 흐름의 단위를 말한다. 

스레드를 생성하는 방법 <Thread 클래스를 상속하는 방법, Runnable 인터페이스를 구현하는 방법> 

 

 

<Thread 클래스를 상속하는 방법 >

class Count extends Thread{
	public void run(){
    	for(int i=0;i<10;i++)
        	System.out.print(i);
    }
}

 

public class Test{
	public static void main(String args[]){
    	Thread t= new Counting();
        t.start();
    }
}

//실행 결과
//0
//1
//...
//9

 

<Runnable 인터페이스를 구현하는 방법>

1. Runnable을 구현하는 클래스를 생성한다. 

2. Runnable 클래스에 run() 메소드를 작성한다. 

3. Thread 클래스의 인스턴스를 생성하고, Runnable 객체를 Thread 생성자의 매개변수로 넘긴다 

4. Thread 객체의 start() 메소드를 호출하여야 한다. 

 

class Counting implements Runnable{
	public void run(){
    	for(int i=0;i<10;i++)
        	System.out.println(i);
    }
}

 

public class Test{
	public static void main(String args[]){
    	Counting c= new Counting();
        Thread t= new Thread(c);
       	t.start();
    }
}

 

 

자바에서 다중 상속이 불가능 한 것을 감안 한다면 Runnable 인터페이스를 사용 하는 것이 좋다. 

Runnable 인터페이스를 사용하면 고수준의 스레드 관리 API도 사용 할 수 있다. 

 

 

 

병렬처리를 구현하는 방법 : 

1. 다중 프로세스

2. 다중 스레드 

 

다중 프로세스는 각 프로세스가 별도의 메모리 공간을 할당 받기 때문에 각 프로세스 간에 데이터를 어떻게 주고 받을 것인지가 이슈 이다 .(IPC)

 

우리가 할 것은 다중 쓰레드 : 각 쓰레드 (명령처리흐름) 들이 하나의 프로세스 안에서 공통된 메모리 공간을 공유하기 때문에 교통 정리를 해주는 것이 이슈 이다. 

 

 

 

 

 스레드는 thread 클래스가 담당한다 

 

start(), run()

 

Thread 객체의 start() 메소드가 호출 되면 이때 " 새로운 명령처리 흐름(쓰레드)" 가 생성되는이 이 쓰레드를 파생쓰레드 라고 한다. 

얘의 역할은 run() 함수를 한번 실행하는 작업을 수행. 

 

start() -> 리턴으로 쓰레드 하나 생성-> run() 한번 실행. 

 

==> 프로그램이 실행되면 처음 만들어지는 쓰레드 하나, 얘는 하는일이 main()함수를 한번 실행시킨다.  

     -> 얘는 main thread 

 

프로그램이 실행될때 반드시 만들어지는 쓰레드가 있느데 이게 메인 쓰레드 그리고  얘 말고 다른 스레드가 만들어지는데 걔가 파생 쓰레드 

 

생성 상태와 실행 가능 상태 / 실행 중지상태 

생성 상태 

-> Thread 클래스를 이용하여 새로운 스레드를 생성

-> start() 는 생성된 스레드를 시작 

-> stop() 은 생성된 스레드를 멈추게 한다. 

 

실행 가능 상태  

-> 스레드가 스케줄링 큐에 넣어지고 스케줄러에 의해 우선순위에 따라 실행 

 

실행 중지상태

실행 가능한 상태에서 다음의 이벤트가 발생하면 실행 중지 상태로 된다. 

-> 스레드나 다른 스레드가 suspend()를 호출하는 경우 

-> 스레드가 wait() 를 호출하는 경우 

-> 스레드가 sleep()을 호출 하는 경우 

-> 스레드가 입출력 작업을 위해 대기하는 경우 

 

<강제적인 종료> 

Thread my=new Thread();

my.start();
try{
	Thread.currentThread().sleep(1000);
} catch(InterruptedException e){}
my.stop();

 

 

 

 

<스레드 스케줄링> 

 

public class CountDown{
	public static void main(String args[]) throws InterruptedException {
    	for(int i=10;i>=0;i--){
        //1초 동안 중단
        	Thread.sleep(1000);
           // 카운트다운을 재개한다. 
           System.out.println(i);
         }
     }
}

//실행 결과
//10
//9
//...
//0

 

 

동기화(synchronization) 한번에 하나의 스레드만이 공유 데이터를 접근 할 수 있도록 제어하는 것이 필요하다 

 

synchronized 는 보호하고자 하는 변수, 메소드 등에 사용 하는 것이다. 

 

1. 이렇게 메소드 앞에 synchronized 키워드를 사용한다면 한 쓰레드가 해당 메소드에 접근할때 lock 을 가지고 들어간다. 

2. 다른 쓰레드가 해당 메소드에 또 접근 하려 한다면 lock 을 가지고 있지 않기 때문에 접근을 하지 못한다. 

3. lock 을 가지고 있던 스레드가 해당 메소드의 실행을 모두 마치면 lock 을 해지하기 때문에 다른 쓰레드가 또 접근이 가능하다 

 

* * 하지만 synchronized는 엄청난 기능저하를 불러오므로, 정확히 동기화가 필요한 곳에서만 synchromized 를 사용함으로서 기능 저하를 최소화 할 수 있다. 

 

synchronized 키워드 사용 방법 

 

// 1. 메서드에서 사용하는 경우

public synchronized void method(){

// 코드

}

 

 

// 2. 객체 변수에 사용하는 경우

private Object obj = new Object();

public void exampleMethod(){

synchronized(obj){

//코드 

}

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형