profile image

L o a d i n g . . .

article thumbnail image
Published 2022. 7. 26. 07:05

지난시간 복습 >> 스레드(thread)?

- 프로세스 내부에서 코드의 실행 흐름

 

프로세스?

- 애플리케이션을 실행하면 운영체제로부터 실행에 필요한 메모리를 할당받아 실행

- 실행중인 하나의 애플리케이션

 

 

 

 


Thread 하위 클래스로부터 생성

작업 스레드가 실행할 작업을 Runnable로 만들지 않고 Thread하위클래스로 정의해보자

import java.awt.Toolkit;

public class BeepThread extends Thread{

	@Override
	public void run() {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		for (int i = 0; i < 5; i++) {
			toolkit.beep();
			try {Thread.sleep(500);} catch (Exception e) {}
		}
	}
}

 

public class BeepPrintEx {
	public static void main(String[] args) {
		Thread thread = new BeepThread();
		thread.start(); 
		
		for (int i = 0; i < 5; i++) {
			System.out.println("Beep");
			try {Thread.sleep(500);} catch (Exception e) {}
		}
	}
}

Runnable 생성대신

BeepThread 객체를 생성하고 start()메소드를 호출하여 BeepThread의 run()메소드를 실행했다

 

 

public class BeepPrintEx2 {
	public static void main(String[] args) {
		Thread thread = new Thread() {

			@Override
			public void run() {
				Toolkit toolkit = Toolkit.getDefaultToolkit();
				for (int i = 0; i < 5; i++) {
					toolkit.beep();
					try {Thread.sleep(500);} catch (Exception e) {}
				}
			}
		};
		thread.start();
		
		for (int i = 0; i < 5; i++) {
			System.out.println("Beep");
			try {Thread.sleep(500);} catch (Exception e) {}
		}
	}
}

익명자식객체를 이용해서 작업스레드를 이렇게도 만들 수 있다.

 

 

 

 

 

 


스레드의 이름

디버깅 시 어떤 스레드가 어떤 작업을 하는지 조사할 목적으로 가끔 사용

main thread는 main이라는 이름을 가지고 있고

직접 생성한 스레드는 자동적으로 Thread-n이라는 이름으로 설정된다.

여기서 n은 스레드의 번호를 의미함. 

 

다른 이름으로 변경시엔

thread.setName("스레드이름");

setName()메소드를 이용해서 변경한다

 

 

 

public class ThreadNameEx {
	public static void main(String[] args) {
		Thread mainThread = Thread.currentThread();
		System.out.println("프로그램 시작 스레드 이름 : " + mainThread.getName());
		
		ThreadA threadA = new ThreadA();
		System.out.println("작업 스레드 이름 : " + threadA.getName());
		threadA.start();
		
		ThreadB threadB = new ThreadB();
		System.out.println("작업 스레드 이름 : " + threadB.getName());
		threadB.start();
	}
}

 

 

 

 


동기화 메소드

싱글 스레드 프로그램에서는 1개의 스레드가 객체를 독차지해서 사용하면 되나,

멀티스레드 프로그램에서는 스레드들이 객체를 공유해서 작업해야 한다. 

 

공유 객체 사용시 주의점

- 스레드 A 가 사용하던 객체를 스레드 B가 상태를 변경할 수 있다

 

>>> 내부의 동기화 메소드를 실행하여 즉기 객체에 잠금을 걸어 다른 스레드가 동기화 메소드를 실행할 수 없도록 한다

public synchronized void method() {
	임계영역; // 단 하나의 스레드만 실행
}

메소드선언에 synchronized 키워드를 사용한다. 이는 정적메소드, 인스턴스메소드 어디든 붙일 수 있다.

 

임계영역 : 멀티 스레드 프로그램에서 단 하나의 스레드만 실행할 수 있는 코드영역

>> 임계영역 지정을 위해 동기화(synchronized)메소드 사용

 

 

 

 

 

synchronized 예제

public class Calculator {
	private int memory;
	
	public int getMemory() {
		return memory;
	}

//	public void setMemory(int memory) {
	public synchronized void setMemory(int memory) {
		this.memory = memory;
		try {
			Thread.sleep(3000);
		} catch (Exception e) {
			System.out.println(Thread.currentThread().getName() + ": " + this.memory);
		}
	}
}

 

 

public class Calculator {
	private int memory;
	
	public int getMemory() {
		return memory;
	}

//	public void setMemory(int memory) {
	public synchronized void setMemory(int memory) {
		this.memory = memory;
		try {
			Thread.sleep(2000);
			System.out.println(Thread.currentThread().getName() + ": " + this.memory);
		} catch (Exception e) {
		}
	}
}

좌: synchronized로 동기화 메소드 제공 우 : 동기화 없이 공유객체

 

 

 

 

 

 

 

User1 스레드는 Calculator객체의 동기화 메소드인 setMemory()를 실행하는 순간 Caculator객체를 잠금처리한다.

메인 스레드가 User2를 실행하지만 synchronized 메소드인 setMemory()를 실행하지 못하고 User1이 모두 실행할동안 대기한다.

그렇기 때문에 User1스레드는 방해받지않고 안전하게 Calculator 객체를 사용하고 메소드 실행 후 User2스레드가 setMemory메소드를 실행하게 된다.

 

 

 

 

 

 

 

 

참고 :

- 혼자공부하는자ㅏ(신용권), 한빛미디어

 

반응형

'개발 > JAVA' 카테고리의 다른 글

[Java] 컬렉션 프레임워크 - List, Set  (0) 2022.08.14
[Java] 스레드 제어  (0) 2022.07.27
[Java] 멀티 스레드 1  (0) 2022.07.25
[Java] java.util 패키지 내 Date, Calendar 클래스  (0) 2022.07.21
[Java] java.lang 패키지  (0) 2022.07.20
복사했습니다!