GDJ 9/11

Yongha Hwang·2023년 9월 11일
0

Thread

Thread 는 어떤 program을 실행 하게 해주는 원동력 이다.

  • 대표적으로 main(String[] args) 는 thread를 동작하게 해 주는 method 이다.

  • Process 간에는 memory share 가 되지 않는다. Thread 간에는 memory share 가 된다.

1. Multi Thread

Main Thread 는 자신을 위해 일할 work Thread를 생성 할 수 있다. 이것을 Multi Thread라고 한다.

  • Thread 생성
		// 워크 스레드 생성 - Runnable Interface 를 구현받는 방법
		Runnable run = new WorkThread(); // 1. 해야할 일 객체화
		Thread thread = new Thread(run); // 2. 쓰레드에 해야할 일을 넣어 준다.
       // 두 방법 모두 익명객체를 활용할 수 있다.
		// 클래스를 익명객체로 사용할 경우
		Thread work = new Thread() {
			@Override
			public void run() {
				for (int i = 1; i <=5; i++) {
					System.out.println("work thread 가 하는 일...");
					try {
						Thread.sleep(500);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}			
		};       
  • Name
    Thread 가 여러 개다 보면 각각의 이름이 필요 하다. 이름을 지정하지 않으면 Thread-n(0부터 시작) 형태의 이름이 자동 지정 된다.

    • thread.steName("스레드 이름");//이름 지정
    • thread.getName();//이름 가져오기
  • 제어
    여러 Thread 를 실행 하면 순서가 제멋대로 이다. (Thread는 Round Robin 방식을 사용 하기 때문 - 일이 빨리 끝난 순서대로 다음 일을 받는 방식)

2. Synchronized

Thread는 memory 를 공유 하기 때문에 객체 간의 데이터 간섭이 일어나 이를 막기 위해 작업이 끝나기 전에는 접근하지 못하게 하는 동기화(Synchronize)를 사용한다.

  • Synchronize method
	//동기화 메서드 사용 - 누군가가 사용하고 있으면 메서드 밖에 "줄 서" 있는다.
	public synchronized void setScore(int score) {
		this.score = score; // 컴퓨터가 하는일은 사용자가 만든 점수를 저장하는 것
		try {
			Thread.sleep(2000); // 그리고 2초간 해당 작업자가 잠들도록 한다.
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// 이후 작업자가 자신의 점수를 확인 한다.
		System.out.println(Thread.currentThread().getName()+" : "+this.score);
	}
  • Synchronize block
		// 동기화 블록 - 메서드 안으로는 여러 스레드가 들어갈 수 있지만, 특정 블록에서는 "줄 서" 있는다.
	public  void setScore(int score) {
		synchronized (this) {
			// 스레드 들이 마음대로 드나들 수 있다.
			// 하지만 블록 에는 들어가지 못하고 줄 서 있어야 한다.
			this.score = score; // 컴퓨터가 하는일은 사용자가 만든 점수를 저장하는 것
			try {
				Thread.sleep(2000); // 그리고 2초간 해당 작업자가 잠들도록 한다.
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

3.Thread State

Thread 는 생성 부터 종료 까지의 상태 값이 있다. getState()를 통해 현재 상태를 알 수 있다.

4. Thread Control

Thread 는 예상대로 움직이지 않기 때문에 제어 하기 위한 method 들이 존재 한다.

  • sleep() : 주어진 ms 동안 thread를 일시 정지 시킨다.

  • yield() : 특정 스레드에게 제어 권을 양보 한다. (무조건X -> 기회를 준다.)

  • join() : 먼저 실행된 스레드가 다 수행하고 이후 내용을 실행한다.

  • wait() : 스레드를 일시 정지 상태로 만든다

  • notify() : 일시 정지 상태인 스레드 중 하나를 실행 대기 상태로 바꾼다 (랜덤)

  • notifyAll() : 일시 정지된 모든 스레드를 실행 대기 상태로 만든다.
    **wait(), notify(), notifyAll() 을 사용할때는 synchronized 안에서 해야 한다.

  • 스레드를 강제로 종료 하는 방법

		//interrupted 로 정지시키는 방법 1
			try {
				while(true) {
				System.out.println("InterStop 스레드 실행 중...");
				Thread.sleep(1);// InterruptedException 을 활용하려면 sleep이 강제적으로 들어가야 한다.
			}
			} catch (Exception e) {
				System.out.println(e.toString());
				System.out.println("자원정리");
				System.out.println("종료");							
		}
		
		// interrupted 로 정지시키는 방법 2
		while(true) {
			System.out.println("InterStop 스레드 실행 중...");
			if(Thread.interrupted()) { // 인터럽트가 발생했는지 확인하여 정지 시키기
				break;
			}
		}
// 메인 클래스
		StopFlag flag = new StopFlag();
		try {
			// stop flag 를 이용한 정지 방법
			flag.start();
			Thread.sleep(1000);
			flag.stop = true;
            } catch (InterruptedException e) {
			e.printStackTrace();
// 스레드 클래스            
   boolean stop = false; // stop flag : 멈추는 신호를 보내는 깃발
	@Override
	public void run() {
		while(stop==false) {
			System.out.println("Stop Flag Thread 실행 중...");
			break;
		}

5. Demon Thread

Work Thread 와 마찬가지로 main thread에 의해서 생성되어 작업을 돕는 역할을 수행한다.
** life cycle의 차이가 있다.

		WorkThread thread = new WorkThread();
		thread.setDaemon(true);
        // 기본값은 false, true로 설정시 데몬 스레드가 됨
		thread.start();
		
		Thread.sleep(3000);
		
		System.out.println("메인 스레드 종료");
		// work thread 는 메인스레드와 관계 없이 독자적인 수명을 갖는다.
		// demon thread 는 할일이 끝나지 않아도, 메인스레드가 끝나면 같이 끝난다.

0개의 댓글

관련 채용 정보