article thumbnail image
Published 2022. 9. 17. 16:32

 

 

 

 


주요내용
  • 스레드의 생성과 실행
  • 스레드의 이름
  • 임계영역과 락
  • 스레드 상태와 실행제어

 

 

스레드의 생성과 실행

스레드를 생성하는데는 두가지 방법이 있다.

 

1.Thread 클래스를 상속

public class Practice_thread {
    public static void main(String[] args) {
        //Thread클래스를 상속받은 클래스를 인스턴스화하여 스레드를 생성
        ThreadTask2 thread2 = new ThreadTask2();

    }
}


//Thread클래스를 상속받은 클래스 작성
class ThreadTask2 extends Thread{
    //run메서드 바디에 스레드가 수행할 작업 내용 작성
    public void run(){
        for(int i=0;i<50; i++){
            System.out.print("LOL");
        }
    }
}

 

2.Runnable 인터페이스를 구현

public class Practice_thread {
    public static void main(String[] args) {
        //Runnable 인터페이스를 구현한 객체 생성
        Runnable T1 = new ThreadTask1();
        //Runnable 구현 객체를 인자로 전달하면서 Thread클래스를 인스턴스화하여 스레드를 생성
        Thread thread1 = new Thread(T1);

        //위 두줄을 한줄로 축약가능
        //Thread thread1 = new Thread(newThreadTask1());
    }
}

//Runaable 인터페이스를 구현하는 클래스
class ThreadTask1 implements Runnable{
    //run 메서드 바디에 스레드가 수행할 내용 작성
    public void run(){
        for(int i=0; i <=100; i++){
            System.out.println("WoW");
        }
    }
}

 

스레드의 실행

start() 메서드로 스레드를 실행할 수 있다.

정확히는 스레드의 상태를 실행 대기 상태로 만들어줌

thread1.start();
thread2.start();

 

두개의 스레드를 작성한 후 실행하면 다음과 같은 결과가 나온다

OS가 정한 순서에 따라 스레드가 번갈아가며 실행되며 순서는 상황에 따라 바뀜

 

 

스레드 이름변경 메서드 getName()

System.out.println(thread2.getName());

//출력값
//Thread-1 (만들어진 순서에 따라 번호 부여)

스레드 이름설정 메서드 setName

thread1.setName("MARATANG");
 System.out.println(thread1.getName());
 
 //출력값
 //MARATANG

스레드의 주솟값 얻기 currentThread()

실행 중인 스레드의 주소값을 사용해야 하는 상황이 발생한다면 Thread 클래스의 정적 메서드인 currentThread()를 사용

 

 

 

임계영역과 락

 

임계 영역 -하나의 스레드만 코드를 실행할 수 있는 코드 영역 ,

락 - 임계 영역을 포함하고 있는 객체에 접근할 수 있는 권한

 

 

특정 코드 구간을 임계 영역으로 설정할 때에는 synchronized라는 키워드를 사용

 

메서드 전체를 임계영역으로 지정

메서드의 반환 타입 좌측에 synchronized 키워드를 작성

 

이 경우에 메서드가 호출되었을 때, 메서드를 실행할 스레드는 메서드가 포함된 객체의 락을 얻으며 해당 스레드가 락을 반납하기 이전에 다른 스레드는 해당 메서드의 코드를 실행하지 못함.

class exampleClass {
	...
	public synchronized boolean Examplemethod(int a) {
	    if ...
	        return true;
	    }
	    return false;
	}
}

 

 

 

특정 영역을 임계영역으로 지정

synchronized 키워드와 함께 소괄호 안에 해당 영역이 포함된 객체의 참조를 넣은 후 블럭 내에 코드를 작성

 

class exampleClass {
	...
	public boolean Examplemethod(int a) {
			synchronized (this) {
			    if ...
			        return true;
			    }
			    return false;
			}
	}
}

이때는 임계 영역으로 설정한 블럭의 코드로 코드 실행 흐름이 진입 할 때, 해당 코드를 실행하고 있는 스레드가 this에 해당하는 객체의 락을 얻게 된다.

 

 

 

스레드의 상태와 실행제어

 

스레드의 상태

 

NEW-스레드가 생성되고 아직 start()가 되지 않은 상태

RUNNABLE - 실행 중 또는 실행 가능한 상태

BLOCKED -동기화블럭에 의해서 일시정지된 상태(lock이 풀릴 때까지 기다리는 상태)

WAITING,THMED_WAITING - 쓰레드의 작업이 종료되지는 않았지만 실행가능하지 않은 일시정지 상태

TERMINATED - 쓰레드의 작업이 종료된 상태

 

 

생성(NEW) -> 실행대기(RUNNABLE) -> 실행  ->  소멸(TERMINATE)

스레드의 작업이 다 끝나거나 stop()실행되면 소멸

 

             일시정지(WAITING,BLOCKED)

 

 

 

 

실행제어 메서드

 

sleep()

millisecond동안 스레드를 잠시 멈춤

static void sleep(long milliSecond)

이 메서드는 Thread의 클래스 메서드이므로 sleep()을 호출할 때에는 클래스를 통해서 호출하는 것이 좋다.

또intruuept()와 같이 사용되므로  try catch문으로 감싸주어야 함

try { Thread.sleep(3000); } catch (Exception error) {}

 

 

 

inturrept()

일시중지 상태(sleep,join,wait)의 스레드를 실행대기상태로 복귀

void interrupt()

 

 

 

yield()

다른 스레드에게 실행을 양보(Thread의 클라스메서드)

static void yield()

운영 체제의 스케줄러에 의해 3초를 할당 받은 스레드 A가 1초 동안 작업을 수행하다가 yield()를 호출하면 남은 실행 시간 2초는 다음 스레드에게 양보

 

불필요한 반복문이 돌 때 유용하게 사용

public void run() {
		while (true) {
				if (example) {
						...
				}
				else Thread.yield();
		}
}

 

 

 

 

join()

다른 스레드의 작업이 끝날때까지 일시정지상태, 특정 스레드에 대해 동작하는 인스턴스 메서드임

void join()
void join(long milliSecond)

//특정 스레드에 동작하는 인스턴스 메서드
//thread1의 작업이 끝날때까지 대기
try{thread1.join();} catch(Exeption e) {}

 

 

 

wait(),notify()

두 스레드가 교대로 작업을 처리해야 할 경우 사용

'Java' 카테고리의 다른 글

Java - 람다와 메서드 참조  (0) 2022.09.18
Java-삼항연산자  (0) 2022.09.17
Java - 다형성  (0) 2022.09.17
Java - 클라스와 객체,필드와 메서드  (5) 2022.09.17
Java 기초  (0) 2022.09.06
복사했습니다!