thread

Thread

μ“°λ ˆλ“œλΌλŠ” κ°œλ…μ„ μ΄ν•΄ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν”„λ‘œμ„ΈμŠ€μ™€ 병행성(Concurrency)의 κ°œλ…μ„ μ•Œλ©΄ 더 쒋을 것같닀.

ν”„λ‘œμ„ΈμŠ€

ν”„λ‘œμ„ΈμŠ€μ˜ 사전적 μ˜λ―ΈλŠ” μ»΄ν“¨ν„°μ—μ„œ μ‹€ν–‰λ˜κ³  μžˆλŠ” 컴퓨터 ν”„λ‘œκ·Έλž¨μ„ λ§ν•œλ‹€. μ—¬λŸ¬ 개의 ν”„λ‘œμ„Έμ„œλ₯Ό μ‚¬μš©ν•˜λŠ” 것을 λ©€ν‹° ν”„λ‘œμ„Έμ‹±μ΄λΌκ³  ν•˜λ©°, 같은 μ‹œκ°„μ— μ—¬λŸ¬ 개의 ν”„λ‘œκ·Έλž¨μ„ λ„μš°λŠ” μ‹œλΆ„ν•  방식을 λ©€ν‹°νƒœμŠ€ν‚Ή 이라고 ν•œλ‹€.

νŠΉμ§•

  • ν”„λ‘œκ·Έλž¨μ΄ μ‹€ν–‰λ˜λŠ” λ‹¨μœ„

  • λͺ¨λ“  ν”„λ‘œκ·Έλž¨μ€ μ‹€ν–‰ 될 λ•Œ ν•˜λ‚˜ μ΄μƒμ˜ ν”„λ‘œμ„ΈμŠ€λ₯Ό κ°–λŠ”λ‹€.

  • 각 ν”„λ‘œμ„ΈμŠ€λŠ” λ‹€λ₯Έ ν”„λ‘œμ„ΈμŠ€μ˜ λ³€μˆ˜λ‚˜ 자료 ꡬ쑰에 μ ‘κ·Όν•  수 μ—†λ‹€.

  • 각 ν”„λ‘œμ„ΈμŠ€λŠ” λ³„λ„μ˜ μ£Όμ†Œκ³΅κ°„μ—μ„œ μ‹€ν–‰λœλ‹€.

  • 컴퓨터 λ©”λͺ¨λ¦¬μ— μ μž¬λ˜μ–΄ μ‹€ν–‰λ˜μ–΄ μžˆλŠ” ν”„λ‘œκ·Έλž¨μ„ λ§ν•œλ‹€.

  • ν”„λ‘œμ„ΈμŠ€μ˜ μƒνƒœλŠ” 생성, μ‹€ν–‰, μ€€λΉ„, λŒ€κΈ°, μ’…λ£Œκ°€ μžˆλ‹€.

병행성 (Concurrency) == λ™μ‹œμ„±

병렬성과 ν—·κ°ˆλ¦΄ 수 μžˆλŠ”λ° 병행성은 λ™μ‹œμ— μ‹€ν–‰λ˜λŠ” 것 처럼 λ³΄μ΄λŠ” κ²ƒμœΌλ‘œ μ‹±κΈ€μ½”μ–΄μ—μ„œλŠ” μ‹œλΆ„ν• κΈ°λ²•μœΌλ‘œ μˆ˜ν–‰ν•  수 있고 λ©€ν‹°μ½”μ–΄μ—μ„œλŠ” 물리적으둜 λ³‘λ ¬λ‘œ λ™μž‘ν•  수 μžˆλ‹€.

병렬성(Parallelism)은 μ‹€μ œλ‘œ λ™μ‹œμ— μž‘μ—…μ΄ μ²˜λ¦¬λ˜λŠ” κ²ƒμœΌλ‘œ λ©€ν‹°μ½”μ—μ—μ„œλ§Œ λ™μž‘μ΄ κ°€λŠ₯ν•˜λ‹€.

μ“°λ ˆλ“œ

ν”„λ‘œμ„ΈμŠ€μ˜ νŠΉμ •ν•œ μˆ˜ν–‰ 경둜둜 ν”„λ‘œμ„ΈμŠ€κ°€ ν• λ‹Ή 받은 μžμ›μ„ μ΄μš©ν•˜λŠ” μ‹€ν–‰μ˜ λ‹¨μœ„λΌκ³  ν•  수 μžˆλ‹€.

ν•˜λ‚˜μ˜ ν”„λ‘œμ„ΈμŠ€μ—μ„œ μ—¬λŸ¬κ°œμ˜ μŠ€λ ˆλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 것을 λ©€ν‹° μŠ€λ ˆλ”©μ΄λΌκ³  ν•œλ‹€.

νŠΉμ§•

  • ν”„λ‘œμ„ΈμŠ€ λ‚΄μ—μ„œ μŠ€νƒ/λ ˆμ§€μŠ€ν„°λ§Œ 각각 ν• λ‹Ή λ°›κ³  λ‚˜λ¨Έμ§€ λ©”λͺ¨λ¦¬ μ˜μ—­μ€ κ³΅μœ ν•œλ‹€. μŠ€νƒμ€ 각각 ν• λ‹Ήν•˜λŠ” 이유 : μŠ€λ ˆλ“œλŠ” ν•œ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 독립적인 λ‹¨μœ„λ‘œμ¨ μ΅œμ†Œν•œμ˜ λ©”λͺ¨λ¦¬ μ˜μ—­(μŠ€νƒ)은 각각 ν• λ‹Ήν•΄μ•Ό λ…λ¦½μ μœΌλ‘œ μˆ˜ν–‰μ΄ κ°€λŠ₯ν•˜λ‹€.

Thread ν΄λž˜μŠ€μ™€ Runnable μΈν„°νŽ˜μ΄μŠ€

μžλ°”μ—μ„œ μ“°λ ˆλ“œλ₯Ό μž‘μ„±ν•˜λŠ” λ°©λ²•μ—λŠ” Thread ν΄λž˜μŠ€μ™€ Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λŠ” 두가지 방법이 μžˆλ‹€.

Thread 클래슀 extends

public class Example {
  public static void main(String[] args){
    ExampleThread th1 = new ExampleThread();
    Thread th2 = new Thread(){
      @Override
      public void run(){
        System.out.println("thread2");
      }
    }

    th1.start();
    th2.start();
  }

  class ExampleThread extends Threads{
    @Override
    public void run(){
      System.out.println("Thread 1");
    }
  }
}

Thread 클래슀λ₯Ό ν™•μž₯ν•˜μ—¬ μƒμ„±ν•˜λŠ” λ°©λ²•μœΌλ‘œλŠ” thread클래슀λ₯Ό 상속받아 μƒμ„±ν•˜λŠ” 방법인 th1κ³Ό th2와 같이 읡λͺ… 객체λ₯Ό μ‚¬μš©ν•˜μ—¬ μƒμ„±ν•˜λŠ” 방법 2κ°€μ§€ κ°€ μ‘΄μž¬ν•˜κ³  λ‘λ²ˆμ§Έλ°©λ²•μΈ 읡λͺ… 클래슀λ₯Ό μ΄μš©ν•˜λŠ” 방법은 μ“°λ ˆλ“œκ°€ 였직 ν•œλ²ˆλ§Œ μˆ˜ν–‰ λ λ•Œ μ‚¬μš©ν•˜λŠ” 방법이닀.

Runnable μΈν„°νŽ˜μ΄μŠ€ implements

public class Example {
  public static void main(String[] args){
    Runnable r = new ExampleThread();
    Thread th1 = new Thread(r);
    //Thread th1 = new Thread(new ExampleThread());

    Thread th2 = new Thread(()->{
      System.out.println("thread2");
    });

    th1.start();
    th2.start();
  }

  class ExampleThread implements Runnalbe{}
    @Override
    public void run(){
      System.out.println("Thread 1");
    }
  }
}

Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•œ Thread생성방법도 두가지가 μ‘΄μž¬ν•œλ‹€.

  1. Runnalbe μΈν„°νŽ˜μ΄μŠ€λ₯Ό implementsν•œ classλ₯Ό μƒμ„±μž λ§€κ°œλ³€μˆ˜λ‘œ μ΄μš©ν•˜μ—¬ μƒμ„±ν•˜λŠ” 방법

  2. Runnable μΈν„°νŽ˜μ΄μŠ€λŠ” runλ©”μ„œλ“œλ°–μ— μ‘΄μž¬ν•˜μ§€ μ•ŠλŠ” 점을 μ΄μš©ν•˜μ—¬ λžŒλ‹€λ₯Ό μ΄μš©ν•΄ λ°”λ‘œ runλ©”μ„œλ“œλ₯Ό μ •μ˜ν•˜μ—¬ μƒμ„±ν•˜λŠ” 방법

차이점

  1. Thread 클래슀λ₯Ό extendsν•˜λŠ” 방법은 classλ₯Ό μƒμ†λ°›λŠ” 것인 만큼 Thread의 λ‹€λ₯Έ λ©”μ„œλ“œλ“€μ„ 이용이 κ°€λŠ₯ν•˜μ§€λ§Œ λ‹€λ₯Έ classλ₯Ό 상속받지 λͺ»ν•˜μ§€λ§Œ, Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜λŠ” 것은 λ‹€λ₯Έ classλ₯Ό 상속받을 수 있고 쑰금 더 객체 μ§€ν–₯적이닀.

  2. Thread클래슀λ₯Ό μƒμ†λ°›λŠ” classλŠ” run λ©”μ„œλ“œκ°€ μ’…λ£Œλ˜λ©΄ κ°€λΉ„μ§€ μ»¬λ ‰μ…˜μ΄ 되기 λ•Œλ¬Έμ— μž¬μ‚¬μš©μ΄ λΆˆκ°€λŠ₯ν•˜μ§€λ§Œ, Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 방법은 Thread ν΄λž˜μŠ€λŠ” κ°€λΉ„μ§€ μ»¬λž™μ…˜μ΄ λ˜λ”λΌλ„ κ΅¬ν˜„μ²΄λŠ” κ°€λΉ„μ§€ μ»¬λž™μ…˜μ΄ λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— μž¬μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

  3. Runnable μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ 경우 Thread클래슀의 λ©”μ„œλ“œλ₯Ό μ΄μš©ν•˜κ³  μ‹Άλ‹€λ©΄ Thread 클래슀의 static λ©”μ„œλ“œμΈ currentThread()λ₯Ό ν˜ΈμΆœν•˜μ—¬ μ“°λ ˆλ“œμ˜ μ°Έμ‘°λ₯Ό μ–»μ–΄μ•Ό μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

class ThreadA extends Thread  {
public void run() {
  System.out.println(getName());
}

class ThreadB implements Runnable {
  public void run() {
    System.out.println(Thread.currentThread().getName());
  }
}

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

μƒνƒœ
μ—΄κ±° μƒμˆ˜
μ„€λͺ…

객체 생성

NEW

μŠ€λ ˆλ“œ 객체 생성 (start()λ©”μ„œλ“œ 호좜 μ „)

μ‹€ν–‰ λŒ€κΈ°

RUNNABLE

μŠ€μΌ€μ€„λ§ λ˜μ§€ μ•Šμ•„ 싀행을 기닀리고 μžˆλŠ” μƒνƒœ

μΌμ‹œμ •μ§€

WAITING

λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ notifyλ₯Ό κΈ°λ‹€λ¦¬λŠ” μƒνƒœ

μΌμ‹œμ •μ§€

TIMED_WAITING

μ£Όμ–΄μ§„ μ‹œκ°„ λ™μ•ˆ κΈ°λ‹€λ¦¬λŠ” μƒνƒœ

μΌμ‹œμ •μ§€

BLOCKED

μ‚¬μš©ν•˜κ³ μž ν•˜λŠ” 객체의 락이 풀릴 λ•Œ κΉŒμ§€ κΈ°λ‹€λ¦¬λŠ” μƒνƒœ ( 동기화 문제 )

μ’…λ£Œ

TERMINATED

싀행을 마친 μƒνƒœ

Start와 run

start()λŠ” NEWμƒνƒœμ˜ μŠ€λ ˆλ“œλ₯Ό RUNNABLEμƒνƒœλ‘œ λ§Œλ“€μ–΄μ£ΌλŠ” λ©”μ„œλ“œλ‘œ 싀행될 수 μžˆλŠ” λŒ€κΈ° 큐에 λ„£μ–΄μ£ΌλŠ” μ—­ν• (call stack 생성)

run()은 μŠ€λ ˆλ“œκ°€ μŠ€μΌ€μ€„λŸ¬μ— μ˜ν•΄ μ‹€μ œλ‘œ μ‹€ν–‰λ λ•Œ μ‹€ν–‰ν•  λ©”μ„œλ“œμ΄κ³  start()없이 run만 μ‹€ν–‰ν•˜κ²Œ λœλ‹€λ©΄ override된 λ©”μ„œλ“œλ₯Ό κ·ΈλŒ€λ‘œ ν˜ΈμΆœν•  뿐 ν•΄λ‹Ή ThreadλŠ” RUNNABLEμƒνƒœκ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— 메타데이터가 μ‹€ν–‰λŒ€κΈ° 큐에 λ“€μ–΄μžˆμ§€ μ•Šμ•„ μ›ν•˜λŠ” λŒ€λ‘œ λ™μž‘ν•˜μ§€ μ•ŠλŠ”λ‹€.

μ“°λ ˆλ“œ μƒνƒœ μ œμ–΄ λ©”μ„œλ“œ

μ“°λ ˆλ“œ μƒνƒœ λ©”μ„œλ“œ 사진 좜처

Thread ν΄λž˜μŠ€μ— μ •μ˜

λ©”μ„œλ“œ
μ„€λͺ…

interrupt()

μΌμ‹œμ •μ§€μƒνƒœμ˜ μŠ€λ ˆλ“œμ—μ„œ Interrupt μ˜ˆμ™Έλ₯Ό λ°œμƒμ‹œμΌœ μž‘μ—…μ„ λ©ˆμΆ”λΌκ³  μš”μ²­ν•˜λŠ” λ©”μ„œλ“œ

interrupted()

interrupt()κ°€ ν˜ΈμΆœλ˜μ—ˆλŠ”μ§€ μ•Œλ €μ£ΌλŠ” λ©”μ„œλ“œ (λ˜μ—ˆλ‹€λ©΄ true)

join((long millis),(int nanos))

λ™μž‘μ€‘μΈ μž‘μ—…μ„ λ©ˆμΆ”κ³  λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ μ§€μ • μ‹œκ°„λ™μ•ˆ μž‘μ—… μˆ˜ν–‰ν•˜λ„λ‘ λ„˜κ²¨μ£ΌλŠ” λ©”μ„œλ“œλ‘œ μ‹œκ°„μ„ μ§€μ •ν•˜μ§€ μ•ŠμœΌλ©΄ λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ μž‘μ—…μ„ λ§ˆμΉ λ•Œ κΉŒμ§€ κΈ°λ‹€λ¦°λ‹€.

sleep(long millis, (int nonos))

일정 μ‹œκ°„λ™μ•ˆ μŠ€λ ˆλ“œλ₯Ό λ©ˆμΆ”κ²Œ ν•˜λŠ” λ©”μ„œλ“œλ‘œ μΌμ‹œμ •μ§€μƒνƒœλ‘œ λ§Œλ“€κ³  interrupt()κ°€ 호좜되면 μ‹€ν–‰ λŒ€κΈ°μƒνƒœλ‘œ λ§Œλ“ λ‹€. sleep은 항상 싀행쀑인 μŠ€λ ˆλ“œμ— λŒ€ν•΄ μž‘λ™ν•˜κΈ° λ•Œλ¬Έμ— static으둜 μ„ μ–Έλ˜μ–΄ μžˆμ–΄ Thread.sleep(1000)κ³Ό 같이 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

yield()

μŠ€λ ˆλ“œ μžμ‹ μ—κ²Œ μ£Όμ–΄μ§„ μ‹œκ°„μ„ λ‹€μŒ μŠ€λ ˆλ“œμ—κ²Œ μ–‘λ³΄ν•˜λŠ” λ©”μ„œλ“œ

Object ν΄λž˜μŠ€μ— μ •μ˜

νŠΉμ • 객체에 λŒ€ν•œ κ²ƒμ΄λ―€λ‘œ μœ„μ˜ λ©”μ„œλ“œλ‘Έ λ‹€λ₯΄κ²Œ Objectν΄λž˜μŠ€μ— μ •μ˜λ˜μ–΄ μžˆμ–΄ λͺ¨λ“  κ°μ²΄μ—μ„œ 호좜이 κ°€λŠ₯ν•˜κ³  동기화 λΈ”λ‘λ‚΄μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆλ‹€.

λ©”μ„œλ“œ
μ„€λͺ…

notify()

μΌμ‹œμ •μ§€ μƒνƒœμ˜ μŠ€λ ˆλ“œμ€‘ λ‹€λ₯Έ μŠ€λ ˆλ“œλ₯Ό κΉ¨μš°λŠ” λ©”μ„œλ“œλ‘œ RUNNABLEμƒνƒœλ‘œ λ§Œλ“ λ‹€.

notifyAll()

waiting poolμ•ˆμ— μžˆλŠ” λͺ¨λ“  μŠ€λ ˆλ“œλ₯Ό κΉ¨μš°λŠ” λ©”μ„œλ“œλ‘œ κΉ¨μ–΄λ‚œ μŠ€λ ˆλ“œλ“€μ€ λ‹€μ‹œ κ²½μŸμ„ 톡해 μ‹€ν–‰λœλ‹€. 호좜된 객체의 waiting poolλ‚΄μ˜ μŠ€λ ˆλ“œλ“€μ„ λͺ¨λ‘ κΉ¨μš°λŠ” 것

wait()

notify()λ‚˜ notifyAll()을 κΈ°λ‹€λ¦¬λŠ” λ©”μ„œλ“œ

wait(long timeout,(int nanos))

μ§€μ •λœ μ‹œκ°„λ™μ•ˆλ§Œ κΈ°λ‹€λ¦¬λŠ” λ©”μ„œλ“œ

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

μ—¬λŸ¬κ°œμ˜ μ“°λ ˆλ“œκ°€ λ™μž‘ν•˜λ©° 병행성을 μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ μ‹œλΆ„ν• μ„ ν•˜μ—¬ μŠ€μΌ€μ€„λ§μ„ 톡해 μŠ€λ ˆλ“œλ₯Ό λ™μž‘ μ‹œν‚€λŠ”λ° 이λ₯Ό μœ„ν•΄, μžλ°”λŠ” μ“°λ ˆλ“œ ν΄λž˜μŠ€μ— μ–΄λ–€ μ“°λ ˆλ“œλ₯Ό 더 μ€‘μš”ν•˜κ²Œ μƒκ°ν•˜μ—¬ λ™μž‘μ‹œν‚¬μ§€ μ§€μ •ν•˜μ—¬ 더 λ§Žμ€ μž‘μ—…μ‹œκ°„μ„ 갖도둝 ν•  수 있게 ν•΄μ£ΌλŠ” 멀버 λ³€μˆ˜λ₯Ό κ°–κ³  μžˆλ‹€.

μš°μ„ μˆœμœ„μ˜ λ²”μœ„λŠ” 1~10이며 μˆ«μžκ°€ λ†’μ„μˆ˜λ‘ μš°μ„ μˆœμœ„κ°€ λ†’κ³ , 메인 λ©”μ„œλ“œλ₯Ό μˆ˜ν–‰ν•˜λŠ” μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„κ°€ 5μ΄λ―€λ‘œ mainλ©”μ„œλ“œ λ‚΄μ—μ„œ μƒμ„±ν•˜λŠ” μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λŠ” 기본값이 5κ°€ λœλ‹€.

μ“°λ ˆλ“œμ˜ μš°μ„ μˆœμœ„λŠ” μƒλŒ€μ μΈ κ°’μœΌλ‘œ μ ˆλŒ€μ μ΄ 값이 μ•„λ‹ˆλ‹€

λ©”μ„œλ“œ

thread.setPriority(1~10);
thread.setPriority(Thread.MIN_PRIORITY); //1
thread.setPriority(Thread.NORM_PRIORITY); //5
thread.setPriority(Thread.MAX_PRIORITY);  //10

μˆœν™˜ν• λ‹Ή (Round Robin) 방식

μŠ€μΌ€μ€„λ§ λ°©μ‹μ—λŠ” μš°μ„ μˆœμœ„λ°©μ‹ 말고도 RR방식도 μžˆλŠ”λ° 이 방식은 μŠ€λ ˆλ“œλ§ˆλ‹€ μ‚¬μš©ν•  μ‹œκ°„μ„ ν• λ‹Ή(Time slice)ν•΄μ„œ μ •ν•΄μ§„ μ‹œκ°„λ§ŒνΌ λŒμ•„κ°€λ©° μ‹€ν–‰ν•˜λŠ” λ°©μ‹μœΌλ‘œ JVM에 μ˜ν•΄ κ²°μ •λ˜κΈ° λ•Œλ¬Έμ— κ°œλ°œμžκ°€ μž„μ˜λ‘œ μˆ˜μ •ν•  수 μ—†λ‹€.

Main μ“°λ ˆλ“œ

μš°λ¦¬κ°€ μžλ°”ν”„λ‘œμ νŠΈλ₯Ό 처음 μ‹œμž‘ν–ˆμ„λ•Œλ‚˜ c,c++와 같이 처음 μž‘μ„±ν•˜λŠ” main()λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ‹œμž‘λ˜λŠ” μŠ€λ ˆλ“œλ‘œ mainλ©”μ„œλ“œμ˜ μ½”λ“œ 흐름이닀.

main μ“°λ ˆλ“œλ₯Ό 톡해 λ‹€λ₯Έ μ“°λ ˆλ“œλ₯Ό μƒμ„±ν•˜κΈ° λ•Œλ¬Έμ— λ©”μΈμŠ€λ ˆλ“œκ°€ μ—†λ‹€λ©΄ λ©€ν‹°μŠ€λ ˆλ“œλŠ” λ‹Ήμ—°νžˆ κ΅¬ν˜„ν•  수 μ—†λ‹€.

single process single thread

single process single thread

single process multi thread

single process multi thread

multi process single thread

multi process single thread

multi process multi thread

multi process multi thread

동기화

λ©€ν‹° μŠ€λ ˆλ“œλ‘œ λ™μž‘ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ—μ„œ ν•œ μŠ€λ ˆλ“œκ°€ μž‘μ—…ν•˜λŠ” 쀑에 μ‚¬μš©ν•˜λŠ” 데이터듀을 λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ κ°„μ„­ν•˜μ§€ λͺ»ν•˜λ„둝 λ§‰λŠ” 것이닀.

동기화λ₯Ό μ‹œν‚€μ§€ μ•ŠλŠ”λ‹€λ©΄ μ—¬λŸ¬κ°œμ˜ μŠ€λ ˆλ“œκ°€ λ²ˆκ°ˆμ•„κ°€λ©° λ™μž‘ν•  경우, μ–΄λ–€ μŠ€λ ˆλ“œκ°€ λ¨Όμ € 싀행될지 μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ— κ°œλ°œμžκ°€ μ˜λ„ν•˜μ§€ μ•ŠλŠ” λ™μž‘μ΄ λ°œμƒν•  수 있기 λ•Œλ¬Έμ— λ©€ν‹°μŠ€λ ˆλ“œν”„λ‘œκ·Έλž˜λ°μ—μ„œλŠ” μ€‘μš”ν•œ λ¬Έμ œμ΄λ‹€.

μ£Όμš” κ°œλ…λ“€

  • μž„κ³„ ꡬ역 (Critical Section) : μ—¬λŸ¬κ°œμ˜ μŠ€λ ˆλ“œκ°€ κ³΅μœ ν•˜λŠ” 데이터 λΈ”λŸ­μœΌλ‘œ ν•˜λ‚˜μ˜ μŠ€λ ˆλ“œλ§Œ μ ‘κ·Όκ°€λŠ₯ν•˜λ„λ‘ μ§€μ •ν•˜λŠ” 것이 λͺ©ν‘œμ΄λ‹€.

  • μƒν˜Έ 배제 (Mutual Exclusion,Mutex) : μž„κ³„ ꡬ역을 ν—Œ μ‹œμ μ—μ„œ ν•œκ°œμ˜ μŠ€λ ˆλ“œλ§Œ μ‚¬μš©ν•  수 μžˆλ„λ‘ λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ 접근을 μ œμ–΄ν•˜λŠ” 기법

  • 동기화 : μƒν˜Έλ°°μ œμ˜ ν•œ ν˜•νƒœλ‘œ μƒν˜Έλ°°μ œλ₯Ό μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ ν”„λ‘œμ„ΈμŠ€μ˜ 처리 μˆœμ„œλ₯Ό κ²°μ •ν•˜λŠ” 기법 (Semaphore)

  • κΈ°μ•„ μƒνƒœ (starvation) : λ‹€λ₯Έ μ“°λ ˆλ“œμ—κ²Œ μš°μ„ μˆœμœ„κ°€ λ°€λ € μžμ›μ„ 계속 ν• λ‹Ήλ°›μ§€ λͺ»ν•˜λŠ” μƒνƒœ

  • 곡정성(fairness) : λͺ¨λ“  μ“°λ ˆλ“œκ°€ κ³΅ν‰ν•˜κ²Œ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ” 것

Synchronized 이용

μž„κ³„μ˜μ—­μ„ μ„€μ •ν•˜λŠ”λ° μ‚¬μš©ν•˜λŠ” ν‚€μ›Œλ“œλ‘œ λ©”μ„œλ“œ 전체λ₯Ό μž„κ³„μ˜μ—­μœΌλ‘œ μ§€μ •ν•˜κ±°λ‚˜ νŠΉμ •ν•œ μ˜μ—­μ„ μž„κ³„μ˜μ—­μœΌλ‘œ μ§€μ •ν•˜λŠ” 방법이 μžˆλ‹€.

1. λ©”μ„œλ“œ 전체λ₯Ό μž„κ³„ μ˜μ—­μœΌλ‘œ μ§€μ •
  public synchronized void cal()  {
    ...
  }

2. νŠΉμ •ν•œ μ˜μ—­μ„ μž„κ³„ μ˜μ—­μœΌλ‘œ μ§€μ •
  synchronized(객체의 μ°Έμ‘°λ³€μˆ˜)  {
    ...
  }

μ“°λ ˆλ“œλŠ” synchronizedκ°€ 호좜된 μ‹œμ λΆ€ν„° ν•΄λ‹Ή μ½”λ“œλΈ”λŸ­μ΄ ν¬ν•¨λœ 객체의 lock을 μ–»μ–΄ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λ‹€κ°€ μ’…λ£Œλ˜λ©΄ lock이 λ°˜ν™˜λ˜κ³  μ΄λŠ” λͺ¨λ‘ μžλ™μœΌλ‘œ 이루어지기 λ•Œλ¬Έμ—, κ°œλ°œμžλŠ” μž„κ³„μ˜μ—­λ§Œ μ„€μ • ν•΄μ£Όλ©΄λœλ‹€.

κ°μ²΄λŠ” lock을 ν•˜λ‚˜μ”© κ°€μ§€κ³  있고 μ„€μ •ν•œ 객체의 lock을 κ°€μ§€κ³ μžˆλŠ” μ“°λ ˆλ“œλ§Œ μž„κ³„μ˜μ—­μ— 접근이 κ°€λŠ₯ν•˜κ³  λ‹€λ₯Έ μŠ€λ ˆλ“œλŠ” λŒ€κΈ° μƒνƒœμ— λ“€μ–΄κ°€κΈ° λ•Œλ¬Έμ— μž„κ³„μ˜μ—­μ€ μ’νžˆλŠ” 것이 μ’‹λ‹€.

λ©”μ„œλ“œμ— synchronizedλ₯Ό κ±Έλ©΄ κ·Έ λ©”μ„œλ“œκ°€ ν¬ν•¨λœ 객체(this)에 lock을 κ±°λŠ” 것과 κ°™λ‹€.

객체 없이 ν˜ΈμΆœν•˜λŠ” static λ©”μ„œλ“œμ˜ 경우 ν•΄λ‹Ή class에 lock을 κ±Έλ©΄μ„œ ν•¨μˆ˜κ°„μ— lock이 κ³΅μœ λ˜μ–΄ λ™μ‹œμ— ν˜ΈμΆœλ˜λŠ” 것을 막아 λ™κΈ°ν™”λ¬Έμ œκ°€ ν•΄κ²°λœλ‹€.

Locks

Java 5에 μΆ”κ°€λœ νŒ¨ν‚€μ§€λ‘œ java.util.concurrentκ°€ μžˆλŠ”λ° 이 νŒ¨ν‚€μ§€μ—μ„œ 동기화λ₯Ό μœ„ν•΄ λ‹€μ–‘ν•œ ν΄λž˜μŠ€λ“€μ„ μ œκ³΅ν•œλ‹€.

μ£Όμš” κΈ°λŠ₯

  • Locks : μƒν˜Έ 배제λ₯Ό μ‚¬μš©ν•  수 μžˆλŠ” 클래슀

  • Synchronizers : 동기화λ₯Ό μ²˜λ¦¬ν•˜λŠ” 클래슀 제곡 (Semaphore, CountDownLatch, CyclicBarrier, Phaser, Exchanger)

  • Atomic : 동기화가 λ˜μ–΄μžˆλŠ” λ³€μˆ˜ 제곡

  • Executors : μ“°λ ˆλ“œ ν’€ 생성, μ“°λ ˆλ“œ 생λͺ…μ£ΌκΈ° 관리와 같은 κΈ°λŠ₯ 제곡

  • Queue : Thread-safeν•œ Queue 제곡

java.util.concurrent.locks

ν•΄λ‹Ή νŒ¨ν‚€μ§€μ— μƒν˜Έ 배제λ₯Ό μœ„ν•œ Lock API듀이 정이 λ˜μ–΄μžˆκ³ , synchronized 도 lock을 μ΄μš©ν•œ λ™κΈ°ν™”μΈλ§ŒνΌ λ™μΌν•œ λ©”μ»€λ‹ˆμ¦˜μœΌλ‘œ λ™μž‘ν•œλ‹€.

λ‚΄λΆ€μ μœΌλ‘œ synchronizedλ₯Ό μ‚¬μš©ν•΄ κ΅¬ν˜„λ˜μ—ˆκ³ , λ”μš± 더 μœ μ—°ν•˜κ³  μ •κ΅ν•˜κ²Œ μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜κ³  직접 lock을 κ±Έκ³  ν‘ΈλŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•΄μ•Ό ν•œλ‹€.

  • Interface

    • Lock : κ³΅μœ μžμ›μ— ν•œλ²ˆμ— ν•œ μ“°λ ˆλ“œλ§Œ read/writeλ₯Ό μˆ˜ν–‰ κ°€λŠ₯

    • ReadWriteLock : 곡유 μžμ›μ— μ—¬λŸ¬κ°œμ˜ μ“°λ ˆλ“œκ°€ readν•  수 μžˆμ§€λ§Œ writeλŠ” ν•œ μ“°λ ˆλ“œλ§Œ μˆ˜ν–‰ κ°€λŠ₯

    • Condition : wait()κ³Ό notify()λ₯Ό μ“°λ ˆλ“œμ˜ μ’…λ₯˜λ‘œ κ΅¬λΆ„ν•˜μ§€ μ•Šκ³ , 곡유객체의 waiting poll에 λͺ°μ•„ λ„£κ³  각 μ“°λ ˆλ“œλ₯Ό μœ„ν•œ Condition을 λ§Œλ“€μ–΄ 각각의 waiting poolμ—μ„œ λ”°λ‘œ 기닀리도둝 ν•œλ‹€.

      wait(),notify(),notifyAll() λŒ€μ‹  await(),signal(),signalAll()을 μ‚¬μš©ν•œλ‹€.

  • Interface의 κ΅¬ν˜„μ²΄

    • ReentrantLock : Lock의 κ΅¬ν˜„μ²΄λ‘œ μž„κ³„μ˜μ—­μ˜ μ‹œμž‘,쑸료 지점을 λͺ…μ‹œ ν•  수 있게 ν•΄μ€€λ‹€.

    • ReentrantReadWriteLock : ReadWriteLock의 κ΅¬ν˜„μ²΄

    • StampLock : JDK 1.8λΆ€ν„° μΆ”κ°€λ˜μ—ˆκ³ , λ‹€λ₯Έ lockκ³Ό 달리 LockμΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ§€ μ•Šκ³  lock을 κ±Έκ±°λ‚˜ ν•΄μ§€ν• λ•Œ μŠ€νƒ¬ν”„(longνƒ€μž… μ •μˆ˜κ°’)λ₯Ό μ‚¬μš©ν•œλ‹€.

  • μ£Όμš” λ©”μ„œλ“œ

    • lock() : Lock μΈμŠ€ν„΄μŠ€μ— lock을 건닀.

    • lockInterruptibly() : ν˜„μ œ μ“°λ ˆλ“œκ°€ interrupted μƒνƒœκ°€ μ•„λ‹λ•Œ Lock μΈμŠ€ν„΄μŠ€μ— μž κΈˆμ„ κ±Έκ³  interruptedμƒνƒœλΌλ©΄ Exception을 λ°œμƒμ‹œν‚¨λ‹€.

    • tryLock() : μ¦‰μ‹œ LockμΈμŠ€ν„΄μŠ€μ— μž κΈˆμ„ μ‹œλ„ν•˜κ³  성곡여뢀λ₯Ό boolean νƒ€μž…μœΌλ‘œ λ°˜ν™˜ν•œλ‹€.

    • tryLock(long timeout, TimeUnit timeUnit) : 잠금 μ‹€νŒ¨μ‹œ falseλ₯Ό λ°˜ν™˜ν•˜λŠ” 것이 μ•„λ‹Œ μ£Όμ–΄μ§„ μ‹œκ°„λ™μ•ˆ κΈ°λ‹€λ¦°λ‹€.

    • unlock() : LockμΈμŠ€ν„΄μŠ€μ˜ μž κΈˆμ„ ν•΄μ œν•œλ‹€.

    • newCondition() : ν˜„μ œ Lock μΈμŠ€ν„΄μŠ€μ™€ μ—°κ²°λœ Condition 객체λ₯Ό λ°˜ν™˜ν•œλ‹€.

Synchronized 와 Lock의 차이점

SynchronizedλŠ” μ•”μ‹œμ μΈ(implicit) lock이라고 ν•˜μ—¬ λΆˆκ³΅μ • λ¬Έμ œκ°€ λ°œμƒ ν•  수 μžˆμ–΄ μ“°λ ˆλ“œ μˆœμ„œλ₯Ό 보μž₯ν•˜μ§€ μ•Šμ§€λ§Œ Lock은 μˆœμ„œλ₯Ό μ§€μ •ν•  수 μžˆμ–΄ λͺ…μ‹œμ μΈ(explict) lock이라고 ν•œλ‹€.

SynchronizedλŠ” lock을 μžλ™ νšλ“/λ°˜ν™˜ν•΄μ£ΌκΈ° λ•Œλ¬Έμ— μ½”λ“œκ°€ κ°„κ²°ν•˜λ‹€λŠ” μž₯점이 있고, Lock은 ReentrantLock을 μ΄μš©ν•˜λ©΄ μƒμ„±μž 인자λ₯Ό 톡해 곡정/λΆˆκ³΅μ •μ„ μ„€μ • ν•  수 μžˆμ–΄ κ³΅μ •ν•œ lock을 μ‚¬μš©ν•  경우 μžμ› 할당을 μœ„ν•΄ 경쟁이 λ°œμƒν–ˆμ„ λ•Œ 였래 κΈ°λ‹€λ¦° μŠ€λ ˆλ“œμ—κ²Œ lock을 μ œκ³΅ν•˜μ—¬ κΈ°μ•„ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

volatile

λ©€ν‹° μ½”μ–΄ ν”„λ‘œμ„Έμ„œλŠ” μ½”μ–΄λ§ˆλ‹€ λ³„λ„μ˜ μΊμ‹œλ₯Ό κ°–κ³  μžˆλŠ”λ° λ³€μˆ˜ μ•žμ— volatile ν‚€μ›Œλ“œλ₯Ό 뢙이면 μ½”μ–΄κ°€ λ³€μˆ˜μ˜ 값을 μ½μ–΄μ˜¬ λ•Œ μΊμ‹œκ°€ μ•„λ‹Œ λ©”λͺ¨λ¦¬μ—μ„œ μ½μ–΄μ˜€κΈ° λ•Œλ¬Έμ— μΊμ‹œμ™€ λ©”λͺ¨λ¦¬κ°„μ˜ 뢈일치λ₯Ό ν•΄κ²°ν•  수 μžˆλ‹€.

JVM은 데이터λ₯Ό 4byte λ‹¨μœ„λ‘œ μ²˜λ¦¬ν•˜κΈ° λ•Œλ¬Έμ— intλ‚˜ 이보닀 μž‘μ€ νƒ€μž…μ˜ λ°μ΄ν„°λŠ” ν•œλ²ˆμ— μ½κ±°λ‚˜ μ“°λŠ” 것이 κ°€λŠ₯ν•˜λ‚˜ 그보닀 큰 데이터 νƒ€μž…μ΄λΌλ©΄ ν•˜λ‚˜μ˜ λͺ…λ Ήμ–΄λ‘œ 값을 μ½κ±°λ‚˜ μ“Έ 수 μ—†λ‹€. λ•Œλ¬Έμ— λ³€μˆ˜μ˜ 값을 μ½λŠ” κ³Όμ •μ—μ„œ λ‹€λ₯Έ μ“°λ ˆλ“œκ°€ 끼어듀 ν‹ˆμ΄ 있기 λ•Œλ¬Έμ— λ³€μˆ˜λ₯Ό 읽고 μ“°λŠ” λ¬Έμž₯을 synchronizedλΈ”λŸ­μœΌλ‘œ κ°μ‹Έκ±°λ‚˜ λ³€μˆ˜λ₯Ό volatile을 λΆ™μ—¬ μ„ μ–Έν•˜λŠ” λ°©λ²•μœΌλ‘œ μΊμ‹œμ™€ λ©”λͺ¨λ¦¬κ°„ 뢈일치 문제λ₯Ό ν•΄κ²° ν•  수 μžˆλ‹€.

μƒμˆ˜μ—λŠ” volatileλ₯Ό 뢙일 수 μ—†μ–΄ λ³€μˆ˜μ— final을 같이 μ“Έ 수 μ—†λ‹€. (μƒμˆ˜λŠ” λ³€ν•˜μ§€ μ•ŠλŠ” 값이기 λ•Œλ¬Έμ— thread-safeν•˜κΈ° λ•Œλ¬Έμ—)

λ°λ“œλ½

κ΅μ°©μƒνƒœλΌκ³ λ„ ν•˜λ©° μƒν˜Έ λ°°μ œμ— μ˜ν•΄ λ‚˜νƒ€λ‚˜λŠ” 문제둜, λ‘˜ μ΄μƒμ˜ μŠ€λ ˆλ“œκ°€ 데이터λ₯Ό μ μœ ν•œ μƒνƒœμ—μ„œ μ„œλ‘œ λ‹€λ₯Έ μŠ€λ ˆλ“œκ°€ μ μœ ν•˜κ³  μžˆλŠ” 데이터λ₯Ό μš”κ΅¬ν•˜κ²Œλ˜μ–΄ 끝없이 κΈ°λ‹€λ¦¬λŠ” μƒνƒœ

λ°μ΄ν„°λ² μ΄μŠ€ νŠΈλžœμ μ…˜μ—μ„œλ„ λ°œμƒν•˜λŠ”λ° ν•œ νŠΈλžœμž­μ…˜μ—μ„œ ν•œ λ ˆμ½”λ“œμ— μ—…λ°μ΄νŠΈλ₯Ό μˆ˜ν–‰ν•  λ•Œ, 이 λ ˆμ½”λ“œλŠ” μ—…λ°μ΄νŠΈλ₯Ό μœ„ν•΄ λ‹€λ₯Έ νŠΈλžœμž­μ…˜μ˜ 접근을 막도둝 lock을 κ±°λŠ”λ° λ‹€μˆ˜μ˜ νŠΈλžœμ μ…˜μ΄ λ™μ‹œμ— λ ˆμ½”λ“œλ₯Ό μ—…λ°μ΄νŠΈν•˜λ €ν•œλ‹€λ©΄ λ°λ“œλ½μ— 빠질 μœ„ν—˜μ΄ μžˆλ‹€.

λ°λ“œλ½ λ°œμƒ 쑰건(이유)

  1. Mutual Exclusion(Mutex) : μžμ›μ— λ™μ‹œ μ ‘κ·Ό λΆˆκ°€λŠ₯

  2. Hold & Wait : μ μœ ν•˜κ³  기닀리기 (μžμ›μ„ μ μœ ν•œμ±„λ‘œ λ‹€λ₯Έ μŠ€λ ˆλ“œμ˜ μžμ›μ„ λ°˜λ‚©λ°›κΈΈ κΈ°λ‹€λ¦¬λŠ” 것)

  3. No Preemption : μžμ›μ„ κ°•μ œλ‘œ λΊμ–΄μ˜€μ§€ λͺ»ν•¨

  4. Circular Wait : μˆœν™˜ ν˜•νƒœλ‘œ λŒ€κΈ°

λ°λ“œλ½ ν•΄κ²° 방법

  1. λ°λ“œλ½ 예방 : λ°λ“œλ½ λ°œμƒ 쑰건 4κ°€μ§€λ₯Ό μ›μ²œ λ΄‰μ‡„ν•˜λŠ” 방법

  2. λ°λ“œλ½μ˜ νšŒν”Ό : μžμ›μ΄ μ–΄λ–»κ²Œ μš”μ²­λ μ§€μ— λŒ€ν•œ 좔가정보λ₯Ό μ œκ³΅ν•˜λ„λ‘ μš”κ΅¬ν•˜λŠ” κ²ƒμœΌλ‘œ μžμ› ν• λ‹Ήμƒνƒœλ₯Ό κ²€μ‚¬ν•˜λŠ” 방법

  3. λ°λ“œλ½ 탐지 & 회볡 : λ°λ“œλ½μ΄ λ°œμƒν–ˆμ„λ•Œ ν•΄κ²°ν•˜λŠ” 방법

  4. λ°λ“œλ½ λ¬΄μ‹œ : μ•„μ£Ό 적은 ν™•λ₯ λ‘œ λ°λ“œλ½μ΄ λ°œμƒν•œλ‹€λ©΄, λ¬΄μ‹œν•˜λŠ” 방법

λ¬΄μ‹œν•˜κ±°λ‚˜ μž¬μ‹€ν–‰ν•˜λŠ” 편이 μžμ›μ μœΌλ‘œ 더 이득을 λ³Ό μˆ˜λ„ 있기 λ•Œλ¬Έμ— μˆ˜ν–‰ν•˜λŠ” 방법

λ°λ“œλ½ λ°©μ§€ 방법듀

  1. 락 μ •λ ¬ : λͺ¨λ“  락이 항상 같은 μˆœμ„œλ‘œ νšλ“λœλ‹€λ©΄ λ°λ“œλ½μ€ λ°œμƒν•˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ— νš¨κ³Όμ μ΄λ‚˜ 락의 μˆœμ„œλ₯Ό μ•Œκ³  μžˆλŠ” μƒνƒœμ—μ„œλ§Œ μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€. (λ°λ“œλ½ 예방)

  2. 락 νƒ€μž„ 아웃 : 락을 νšλ“ν•˜κΈ° μœ„ν•΄ κΈ°λ‹€λ¦¬λŠ” μ‹œκ°„μ„ 정해놓고 μ‹œκ°„μ΄ μ§€λ‚œ ν›„μ—λŠ” 락을 λ‹€μ‹œ μ‹œλ„ν•˜λŠ” 방법 (λ°λ“œλ½ 탐지&회볡)

같은 락을 νšλ“ν•˜λ €λŠ” λ‹€λ₯Έ λͺ¨λ“  μ“°λ ˆλ“œμ—κ²Œ 기회λ₯Ό μ£ΌλŠ” 것이기 λ•Œλ¬Έμ— 곡정성 λ¬Έμ œκ°€ λ°œμƒν•˜κ²Œλ˜κ³ , λ°λ“œλ½ 뿐만이 μ•„λ‹Œ μž‘μ—…μ„ μ²˜λ¦¬μ€‘μ—λ„ νƒ€μž„μ•„μ›ƒμ΄ λ°œμƒν•  수 도 μžˆλ‹€.

  1. λ°λ“œλ½ 감지 : 자료ꡬ쑰λ₯Ό μ΄μš©ν•˜μ—¬ μ“°λ ˆλ“œκ°€ 락을 νšλ“ν•˜λ©΄ μ €μž₯ν•˜κ³  이λ₯Ό μ΄μš©ν•΄ λ°λ“œλ½μ„ κ°μ§€ν•˜κ³  λ°λ“œλ½μ΄ λ°œμƒν–ˆλ‹€λ©΄, 락을 ν•΄μ œν•˜λŠ” 방법

  2. Atomic Variable : volatile ν‚€μ›Œλ“œλ‚˜ java.util.concurrent.atomic 클래슀λ₯Ό μ΄μš©ν•˜μ—¬ μ›μž λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” 방법

μ“°λ ˆλ“œ ν’€

μ“°λ ˆλ“œλ₯Ό 미리 λ§Œλ“€μ–΄ ν•„μš”ν• λ•Œ μ‚¬μš©ν•˜κ³  λ°˜λ‚©ν•  수 μžˆλ„λ‘ ν•˜λŠ” ν’€μž₯의 κ°œλ…

java.util.concurrent.Executorsμ—μ„œ μŠ€λ ˆλ“œν’€ κ΄€λ ¨ APIλ₯Ό μ œκ³΅ν•œλ‹€.

μž₯점

  • μŠ€λ ˆλ“œλ₯Ό 생성/μˆ˜κ±°ν•˜λŠ”λ° λΉ„μš©μ΄ 적닀.

  • μœ„μ˜ 이유둜 λ‹€μˆ˜μ˜ μ‚¬μš©μž μš”μ²­μ„ μ²˜λ¦¬ν• λ•Œ λΉ λ₯΄κ²Œ λŒ€μ‘ κ°€λŠ₯ν•˜λ‹€.

단점

  • μ‚¬μš©ν•˜λŠ” 양보닀 많이 생성해두면 λ©”λͺ¨λ¦¬ λ‚­λΉ„κ°€ λœλ‹€.

  • λ…ΈλŠ” μŠ€λ ˆλ“œκ°€ λ°œμƒν•  수 μžˆλ‹€.

μ“°λ ˆλ“œ ν’€μ˜ ꡬ쑰

  1. Task의 μš”μ²­μ„ λ°›λŠ” Queue

  2. μ‹€μ œ μ“°λ ˆλ“œλ₯Ό μƒμ„±ν•˜κ³  κ΄€λ¦¬ν•˜λŠ” manager

  3. Queue μ•ˆμ—μ„œ Taskλ₯Ό 꺼내와 μ‹€μ œ μ“°λ ˆλ“œμœ„μ— λ™μž‘μ‹œμΌœ κ²°κ³Όλ₯Ό μ–»λŠ” λΆ€λΆ„

생성 λ©”μ„œλ“œ

  1. Executors.newFixedThreadPool(10) : μ΅œλŒ€ μ“°λ ˆλ“œλ₯Ό 10κ°œκΉŒμ§€ λ§Œλ“œλŠ” ν’€

  2. Executors.newCachedThreadPool() : μ“°λ ˆλ“œ 수의 μ œν•œμ„ 두지 μ•ŠλŠ” ν’€λ‘œ μ“°λ ˆλ“œ μ‹œμž‘ μš”μ²­μ΄ λ“€μ–΄μ˜¬λ•Œ μƒμ„±ν•˜κ³  μ’…λ£Œμ‹œμ— λ°”λ‘œ μ£½μ§€μ•Šκ³  짧은 μ‹œκ°„(1λΆ„)λ™μ•ˆ μ‚΄μ•„μžˆλŠ” λ°©λ²•μ˜ ν’€

  3. Executors.newSingleThreadExecutor() : ν•˜λ‚˜μ˜ μ“°λ ˆλ“œλ₯Ό μƒμ„±ν•˜λŠ” ν’€λ‘œ μ“°λ ˆλ“œ μž‘μ—…μ€‘μ— μ˜ˆμ™Έμƒν™©μ΄ λ°œμƒν•œ 경우 μ˜ˆμ™Έμ²˜λ¦¬λ₯Ό μœ„ν•œ μ“°λ ˆλ“œμš©μœΌλ‘œ 많이 μ‚¬μš©ν•œλ‹€.

  4. Executors.newScheduledThreadPool() : 일정 μ£ΌκΈ°λ§ˆλ‹€ λ°˜λ³΅ν•΄μ•Όν•˜λŠ” μŠ€λ ˆλ“œλ₯Ό μ—¬λŸ¬κ°œ μƒμ„±ν•˜κΈ° μœ„ν•œ ν’€

적정 μŠ€λ ˆλ“œν’€μ˜ μ‚¬μ΄μ¦ˆλŠ” μ–΄λ–»κ²Œ μ•ŒκΉŒ?


Reference

https://nesoy.github.io/articles/2018-09/OS-Concurrency-Parallelism

https://ryan-han.com/post/java/java-thread/

https://zbomoon.tistory.com/12

https://widevery.tistory.com/28

https://goscala.tistory.com/171

https://tourspace.tistory.com/54

Last updated