1. μ“°λ ˆλ“œ


ν”„λ‘œμ„ΈμŠ€μ™€ μ“°λ ˆλ“œ

  • λͺ¨λ“  ν”„λ‘œμ„ΈμŠ€λŠ” μ΅œμ†Œν•œ ν•˜λ‚˜μ˜ μ“°λ ˆλ“œλ₯Ό κ°–κ³  있음
    • ν”„λ‘œμ„ΈμŠ€ : μ‹€ν–‰ 쀑인 ν”„λ‘œκ·Έλž¨, μžμ›κ³Ό μ“°λ ˆλ“œλ‘œ ꡬ성
    • μ“°λ ˆλ“œ : ν”„λ‘œμ„ΈμŠ€ λ‚΄μ—μ„œ μ‹€μ œ μž‘μ—…μ„ μˆ˜ν–‰
  • ν”„λ‘œμ„ΈμŠ€ : μ“°λ ˆλ“œ = 곡μž₯ : 일꾼
    • μ‹±κΈ€ μ“°λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€ = μžμ› + μ“°λ ˆλ“œ
    • λ©€ν‹° μ“°λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€ = μžμ› + μ“°λ ˆλ“œ + μ“°λ ˆλ“œ + … + μ“°λ ˆλ“œ
  • β€œν•˜λ‚˜μ˜ μƒˆλ‘œμš΄ ν”„λ‘œμ„ΈμŠ€λ₯Ό μƒμ„±ν•˜λŠ” 것 보닀 ν•˜λ‚˜μ˜ μƒˆλ‘œμš΄ μ“°λ ˆλ“œλ₯Ό μƒμ„±ν•˜λŠ” 것이 더 적은 λΉ„μš©μ΄ λ“ λ‹€.”

λ©€ν‹°μ“°λ ˆλ“œμ˜ μž₯단점

  • λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž¨μ΄ λ©€ν‹°μ“°λ ˆλ“œλ‘œ μž‘μ„±λ˜μ–΄ μžˆλ‹€. κ·ΈλŸ¬λ‚˜, λ©€ν‹°μ“°λ ˆλ“œ ν”„λ‘œκ·Έλž˜λ°μ΄ μž₯점만 μžˆλŠ” 것은 μ•„λ‹ˆλ‹€.

μž₯점

  • μ‹œμŠ€ν…œ μžμ›μ„ 보닀 효율적으둜 μ‚¬μš©ν•  수 있음
  • μ‚¬μš©μžμ— λŒ€ν•œ 응닡성이 ν–₯상됨
  • μž‘μ—…μ΄ λΆ„λ¦¬λ˜μ–΄ μ½”λ“œκ°€ 간결해짐

단점

  • 동기화에 μ£Όμ˜ν•΄μ•Ό 함
  • κ΅μ°©μƒνƒœ(dead-lock)κ°€ λ°œμƒν•˜μ§€ μ•Šλ„λ‘ μ£Όμ˜ν•΄μ•Ό 함
  • 각 μ“°λ ˆλ“œκ°€ 효율적으둜 κ³ λ₯΄κ²Œ 싀행될 수 있게 ν•΄μ•Ό 함

Java Thread


  • 일반 μŠ€λ ˆλ“œμ™€ 거의 차이가 μ—†μœΌλ©° JVM이 운영체제 역할을 함
  • μžλ°”μ—λŠ” ν”„λ‘œμ„ΈμŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šκ³  μŠ€λ ˆλ“œλ§Œ 쑴재
    • μžλ°” μŠ€λ ˆλ“œλŠ” JVM에 μ˜ν•΄ μŠ€μΌ€μ€„λ˜λŠ” μ‹€ν–‰ λ‹¨μœ„ μ½”λ“œ 블둝
  • μžλ°” μŠ€λ ˆλ“œ μŠ€μΌ€μ€„λ§μ€ μ „μ μœΌλ‘œ JVM에 μ˜ν•΄ 이루어짐
  • JVM이 κ΄€λ¦¬ν•˜λŠ” μŠ€λ ˆλ“œ 정보
    • μŠ€λ ˆλ“œκ°€ λͺ‡ 개 μ‘΄μž¬ν•˜λŠ”μ§€
    • μŠ€λ ˆλ“œλ‘œ μ‹€ν–‰λ˜λŠ” ν”„λ‘œκ·Έλž¨ μ½”λ“œμ˜ λ©”λͺ¨λ¦¬ μœ„μΉ˜λŠ” 어디인지
    • μŠ€λ ˆλ“œμ˜ μƒνƒœλŠ” 무엇인지
    • μŠ€λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λŠ” μ–Όλ§ˆμΈμ§€
  • 즉, κ°œλ°œμžλŠ” μžλ°” μŠ€λ ˆλ“œλ‘œ μž‘λ™ν•  μŠ€λ ˆλ“œ μ½”λ“œλ₯Ό μž‘μ„±ν•˜κ³ , μŠ€λ ˆλ“œ μ½”λ“œκ°€ 생λͺ…을 가지고 싀행을 μ‹œμž‘ν•˜λ„λ‘ JVM에 μš”μ²­ν•˜λŠ” 일 뿐

3~6. μ“°λ ˆλ“œμ˜ κ΅¬ν˜„κ³Ό μ‹€ν–‰


μ“°λ ˆλ“œμ˜ κ΅¬ν˜„κ³Ό μ‹€ν–‰

  1. Thread 클래슀λ₯Ό 상속
  2. Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ (λ‹€λ₯Έ 클래슀λ₯Ό 상속 받을 수 있기 λ•Œλ¬Έμ— 더 μœ μ—°ν•¨)
Runnable r = new MyThread2();
Thread t2 = new Thread(r);
t2.start();

μ“°λ ˆλ“œμ˜ μ‹€ν–‰ - start()

  • μ“°λ ˆλ“œ 생성 ν›„ start()λ₯Ό ν˜ΈμΆœν•΄μ•Ό μ“°λ ˆλ“œκ°€ μž‘μ—…μ„ μ‹œμž‘ν•¨
Thread t1 = new Thread(); // μ“°λ ˆλ“œ t1을 생성
Thread t2 = new Thread(); // μ“°λ ˆλ“œ t2을 생성
t1.start(); // μ“°λ ˆλ“œ t1을 μ‹€ν–‰
t2.start(); // μ“°λ ˆλ“œ t2을 μ‹€ν–‰
  • start()λ₯Ό ν˜ΈμΆœν•˜λ©΄ μ‹€ν–‰ κ°€λŠ₯ν•œ μƒνƒœκ°€ λ˜λŠ” 것. λ°”λ‘œ μ‹€ν–‰λ˜μ§€ μ•ŠμŒ
  • OS μŠ€μΌ€μ₯΄λŸ¬κ°€ μ‹€ν–‰ μˆœμ„œλ₯Ό κ²°μ •. λ¨Όμ € ν˜ΈμΆœλ˜μ—ˆλ‹€κ³  λ¨Όμ € μ‹€ν–‰λ˜μ§€ μ•ŠμŒ

start() 와 run()

  1. start() κ°€ μƒˆλ‘œμš΄ 호좜 μŠ€νƒ(Call stack)을 생성
  2. μƒμ„±λœ 호좜 μŠ€νƒμ—μ„œ run() 이 μ‹€ν–‰ 됨

7~13. μ‹±κΈ€/λ©€ν‹° μ“°λ ˆλ“œ, I/O 블락킹


main μ“°λ ˆλ“œ

  • main λ©”μ„œλ“œμ˜ μ½”λ“œλ₯Ό μˆ˜ν–‰ν•˜λŠ” μ“°λ ˆλ“œ
  • μ“°λ ˆλ“œλŠ” β€˜μ‚¬μš©μž μ“°λ ˆλ“œβ€™ 와 β€˜λ°λͺ¬ μ“°λ ˆλ“œ(보쑰 μ“°λ ˆλ“œ)’ 두 μ’…λ₯˜κ°€ 있음
  • μ‹€ν–‰ 쀑인 μ‚¬μš©μž μ“°λ ˆλ“œκ°€ ν•˜λ‚˜λ„ 없을 λ•Œ ν”„λ‘œκ·Έλž¨μ€ μ’…λ£Œλœλ‹€.

μ‹±κΈ€μ“°λ ˆλ“œμ™€ λ©€ν‹°μ“°λ ˆλ“œ

  • context switching : μ“°λ ˆλ“œμ˜ μž‘μ—… κ°„ λ„˜μ–΄κ°€λŠ” 것

μ“°λ ˆλ“œμ˜ I/O 블락킹

  • I/O 블락킹 : μž…μΆœλ ₯μ‹œ μž‘μ—…μ€‘λ‹¨ ν˜„μƒ
    • λ©€ν‹° μ“°λ ˆλ“œλŠ” μž…μΆœλ ₯을 κΈ°λ‹€λ¦¬λŠ” ꡬ간 λ™μ•ˆ λ‹€λ₯Έ μ“°λ ˆλ“œλ₯Ό μ‚¬μš©ν•  수 μžˆμ–΄ 효율적

14~17. μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„, κ·Έλ£Ή


μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„

  • μž‘μ—…μ˜ μ€‘μš”λ„μ— 따라 μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λ₯Ό λ‹€λ₯΄κ²Œ ν•˜μ—¬ νŠΉμ • μ“°λ ˆλ“œκ°€ 더 λ§Žμ€ μž‘μ—…μ‹œκ°„μ„ κ°–κ²Œ ν•  수 있음
  • 희망사항일 뿐 OS μŠ€μΌ€μ₯΄λŸ¬μ— μ˜ν•΄ μš°μ„ μˆœμœ„κ°€ 정해짐
void setPriority(int newPriority) // μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λ₯Ό μ§€μ •ν•œ κ°’μœΌλ‘œ λ³€κ²½
int  getPriority()                // μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λ₯Ό λ°˜ν™˜
public static final int MAX_PRIORITY  = 10 // μ΅œλŒ€μš°μ„ μˆœμœ„
public static final int MIN_PRIORITY  = 1  // μ΅œμ†Œμš°μ„ μˆœμœ„
public static final int NORM_PRIORITY = 5  // λ³΄ν†΅μš°μ„ μˆœμœ„

μ“°λ ˆλ“œ κ·Έλ£Ή

  • μ„œλ‘œ κ΄€λ ¨λœ μ“°λ ˆλ“œλ₯Ό 그룹으둜 λ¬Άμ–΄μ„œ 닀루기 μœ„ν•œ 것
  • λͺ¨λ“  μ“°λ ˆλ“œλŠ” λ°˜λ“œμ‹œ ν•˜λ‚˜μ˜ μ“°λ ˆλ“œ 그룹에 ν¬ν•¨λ˜μ–΄ μžˆμ–΄μ•Ό 함
  • μ“°λ ˆλ“œ 그룹을 μ§€μ •ν•˜μ§€ μ•Šκ³  μƒμ„±ν•œ μ“°λ ˆλ“œλŠ” β€˜main μ“°λ ˆλ“œ 그룹’에 속함
  • μžμ‹ μ„ μƒμ„±ν•œ μ“°λ ˆλ“œ(λΆ€λͺ¨ μ“°λ ˆλ“œ)의 κ·Έλ£Ήκ³Ό μš°μ„ μˆœμœ„λ₯Ό μƒμ†λ°›μŒ

18~21. 데λͺ¬ μ“°λ ˆλ“œ, μ“°λ ˆλ“œμ˜ μƒνƒœ


데λͺ¬ μ“°λ ˆλ“œ(daemon thread)

  • 일반 μ“°λ ˆλ“œ(non-daemon thread)의 μž‘μ—…μ„ λ•λŠ” 보쑰적인 역할을 μˆ˜ν–‰
  • 일반 μ“°λ ˆλ“œκ°€ λͺ¨λ‘ μ’…λ£Œλ˜λ©΄ μžλ™μ μœΌλ‘œ μ’…λ£Œλ¨
  • 가비지 컬렉터, μžλ™μ €μž₯, ν™”λ©΄ μžλ™κ°±μ‹  등에 μ‚¬μš©λ¨
  • λ¬΄ν•œλ£¨ν”„μ™€ 쑰건문을 μ΄μš©ν•΄μ„œ μ‹€ν–‰ ν›„ λŒ€κΈ°ν•˜λ‹€κ°€ νŠΉμ •μ‘°κ±΄μ΄ 만쑱되면 μž‘μ—…μ„ μˆ˜ν–‰ν•˜κ³  λ‹€μ‹œ λŒ€κΈ°ν•˜λ„λ‘ μž‘μ„±
public void run() {
	while (true) {
		try {
			Thread.sleep(3 * 1000);
		} catch(InterruptedException e) {}
		// autoSave 값이 trueλ©΄ autoSave() 호좜
		if (autoSave) {
			autoSave();
		}
	}
}
// μ“°λ ˆλ“œκ°€ 데λͺ¬μΈμ§€ 확인
boolean isDaemon()
// μ“°λ ˆλ“œλ₯Ό 데λͺ¬ μ“°λ ˆλ“œλ‘œ λ³€κ²½ (λ°˜λ“œμ‹œ start()λ₯Ό ν˜ΈμΆœν•˜κΈ° 전에 μ‹€ν–‰λ˜μ–΄μ•Ό 함)
void setDaemon(boolean on)

μ“°λ ˆλ“œμ˜ μƒνƒœ

μƒνƒœμ„€λͺ…
NEWμ“°λ ˆλ“œκ°€ μƒμ„±λ˜κ³  아직 start()κ°€ ν˜ΈμΆœλ˜μ§€ μ•Šμ€ μƒνƒœ
RUNNABLEμ‹€ν–‰ 쀑 λ˜λŠ” μ‹€ν–‰ κ°€λŠ₯ν•œ μƒνƒœ
BLOCKEDλ™κΈ°ν™”λΈ”λŸ­μ— μ˜ν•΄μ„œ μΌμ‹œμ •μ§€λœ μƒνƒœ(lock이 풀릴 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦¬λŠ” μƒνƒœ)
WAITING, TIMED_WAITINGμ“°λ ˆλ“œμ˜ μž‘μ—…μ΄ μ’…λ£Œλ˜μ§€λŠ” μ•Šμ•˜μ§€λ§Œ μ‹€ν–‰κ°€λŠ₯ν•˜μ§€ μ•Šμ€(unrunnable) μΌμ‹œμ •μ§€μƒνƒœ. TIMED_WAITING은 μΌμ‹œμ •μ§€μ‹œκ°„μ΄ μ§€μ •λœ 경우λ₯Ό 의미
TERMINATEDμ“°λ ˆλ“œμ˜ μž‘μ—…μ΄ μ’…λ£Œλœ μƒνƒœ

22~25. sleep(), interrupt()


sleep()

  • ν˜„μž¬ μ“°λ ˆλ“œ(자기 μžμ‹ )λ₯Ό μ§€μ •λœ μ‹œκ°„λ™μ•ˆ λ©ˆμΆ”κ²Œ 함
static void sleep(long millis)
static void sleep(long millis, int nanos)
  • μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό ν•΄μ•Ό 함 (InterruptedException λ°œμƒ μ‹œ 깨어남)
  • νŠΉμ • μ“°λ ˆλ“œλ₯Ό μ§€μ •ν•΄μ„œ λ©ˆμΆ”κ²Œ ν•˜λŠ” 것은 λΆˆκ°€λŠ₯

interrupt()

  • λŒ€κΈ°μƒνƒœ(WAITING)인 μ“°λ ˆλ“œλ₯Ό μ‹€ν–‰λŒ€κΈ°μƒνƒœ(RUNNABLE)둜 λ§Œλ“¬
void interrupt()             // μ“°λ ˆλ“œμ˜ interrupted μƒνƒœλ₯Ό false μ—μ„œ true 둜 λ³€κ²½
boolean isInterrupted()      // μ“°λ ˆλ“œμ˜ interrupted μƒνƒœλ₯Ό λ°˜ν™˜
static boolean interrupted() // ν˜„μž¬ μ“°λ ˆλ“œμ˜ interrupted μƒνƒœλ₯Ό μ•Œλ €μ£Όκ³ , false 둜 μ΄ˆκΈ°ν™”

26~27. suspend(), resume(), stop()


suspend(), resume(), stop()

  • μ“°λ ˆλ“œμ˜ 싀행을 μΌμ‹œμ •μ§€, 재개, 완전정지 μ‹œν‚΄
  • ν•˜μ§€λ§Œ, deprecated 됨. κ΅μ°©μƒνƒœ(dead-lock)λ₯Ό μΌμœΌν‚¬ κ°€λŠ₯성이 μžˆμ–΄μ„œ ꢌμž₯ X

28~29. join(), yield()


join()

  • μ§€μ •λœ μ‹œκ°„ λ™μ•ˆ νŠΉμ • μ“°λ ˆλ“œκ°€ μž‘μ—…ν•˜λŠ” 것을 κΈ°λ‹€λ¦°λ‹€.
  • μ˜ˆμ™Έμ²˜λ¦¬ ν•΄μ•Ό 함 (InterruptedException이 λ°œμƒν•˜λ©΄ μž‘μ—… 재개)

yield()

  • 남은 μ‹œκ°„μ„ λ‹€μŒ μ“°λ ˆλ“œμ—κ²Œ μ–‘λ³΄ν•˜κ³ , μžμ‹ (ν˜„μž¬ μ“°λ ˆλ“œ)은 μ‹€ν–‰λŒ€κΈ°
  • yield()와 interrupt()λ₯Ό 적절히 μ‚¬μš© μ‹œ, 응닡성과 νš¨μœ¨μ„±μ„ 높일 수 있음

30~33. μ“°λ ˆλ“œμ˜ 동기화


μ“°λ ˆλ“œμ˜ 동기화(synchronization)

  • λ©€ν‹° μ“°λ ˆλ“œ ν”„λ‘œμ„ΈμŠ€μ—μ„œλŠ” λ‹€λ₯Έ μ“°λ ˆλ“œμ˜ μž‘μ—…μ— 영ν–₯을 λ―ΈμΉ  수 있음
  • 진행쀑인 μž‘μ—…μ΄ λ‹€λ₯Έ μ“°λ ˆλ“œμ—κ²Œ 간섭받지 μ•Šκ²Œ ν•˜λ €λ©΄ β€˜λ™κΈ°ν™”β€™κ°€ ν•„μš”
  • μ“°λ ˆλ“œμ˜ 동기화 - ν•œ μ“°λ ˆλ“œκ°€ 진행쀑인 μž‘μ—…μ„ λ‹€λ₯Έ μ“°λ ˆλ“œκ°€ κ°„μ„­ν•˜μ§€ λͺ»ν•˜κ²Œ λ§‰λŠ” 것
  • λ™κΈ°ν™”ν•˜λ €λ©΄ 간섭받지 μ•Šμ•„μ•Ό ν•˜λŠ” λ¬Έμž₯듀을 β€˜μž„κ³„ μ˜μ—­β€™μœΌλ‘œ μ„€μ •
  • μž„κ³„ μ˜μ—­μ€ 락을 얻은 단 ν•˜λ‚˜μ˜ μ“°λ ˆλ“œλ§Œ μΆœμž… κ°€λŠ₯ (객체 1κ°œμ— 락 1개)

synchronizedλ₯Ό μ΄μš©ν•œ 동기화

  • synchronized둜 μž„κ³„μ˜μ—­(lock이 κ±Έλ¦¬λŠ” μ˜μ—­)을 μ„€μ •ν•˜λŠ” 방법 2가지
// 1. λ©”μ„œλ“œ 전체λ₯Ό μž„κ³„ μ˜μ—­μœΌλ‘œ 지정
public synchronized void calcSum() {
	...
}
// 2. νŠΉμ •ν•œ μ˜μ—­μ„ μž„κ³„ μ˜μ—­μœΌλ‘œ 지정
synchronized(객체의 μ°Έμ‘°λ³€μˆ˜) {
	...
}

34~36. wait(), notify()


wait(), notify()

  • λ™κΈ°ν™”μ˜ νš¨μœ¨μ„ 높이기 μœ„ν•΄ wait(), notify()λ₯Ό μ‚¬μš©
  • Object ν΄λž˜μŠ€μ— μ •μ˜λ˜μ–΄ 있으며, 동기화 블둝 λ‚΄μ—μ„œλ§Œ μ‚¬μš© κ°€λŠ₯
    • wait() - 객체의 lock을 ν’€κ³  μ“°λ ˆλ“œλ₯Ό ν•΄λ‹Ή 객체의 waiting pool에 λ„£μŒ
    • notify() - wating poolμ—μ„œ λŒ€κΈ°μ€‘μΈ μ“°λ ˆλ“œ 쀑 ν•˜λ‚˜λ₯Ό 깨움
    • notifyAll() - wating poolμ—μ„œ λŒ€κΈ°μ€‘μΈ λͺ¨λ“  μ“°λ ˆλ“œλ₯Ό 깨움