๐Ÿ“– Java ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ, ๋ณ‘ํ–‰์„ฑ ๋ฐ ์„ฑ๋Šฅ ์ตœ์ ํ™” (์ง„ํ–‰์ค‘)

๊ธ€๋˜ 9๊ธฐ & Udemy ์ง€์›์„ ๋ฐ›์•„ ๋“ฃ๊ฒŒ ๋œ ๊ฐ•์˜ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•œ ํŽ˜์ด์ง€์ž…๋‹ˆ๋‹ค.



1. ๊ฐœ์š”

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋Š” ์‘๋‹ต์„ฑ๊ณผ ์„ฑ๋Šฅ์„ ์œ„ํ•ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์‘๋‹ต์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™์˜์ƒ์ด ์ง„ํ–‰์ค‘์—๋„ UI๋กœ ๋งˆ์šฐ์Šค๋ฅผ์›€์ง์—ฌ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—…์ด ๋™์‹œ์— ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š”๋ฐ ์‚ฌ์‹ค์€ Task์— ๋”ฐ๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์„ ๋‚˜๋ˆ„์–ด ์ฒ˜๋ฆฌํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๋ณ‘ํ–‰์„ฑ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋งŽ์€ ์ฝ”์–ด๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋งŽ์€ ์„œ๋น„์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๊ณ„ ๋Œ€์ˆ˜๋ฅผ ์ค„์ด๊ณ  ํ•˜๋“œ์›จ์–ด ๋น„์šฉ์„ ์ ˆ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šด์˜์ฒด์ œ๋Š” ํ•˜๋“œ ๋””์Šคํฌ์—์„œ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋กœ๋“œ๋˜๊ณ  ์šด์˜์ฒด์ œ๋Š” ํ•˜๋“œ์›จ์–ด CPU ์‚ฌ์ด ์ƒํ˜ธ์ž‘์šฉ์„ ๋•์Šต๋‹ˆ๋‹ค. ๊ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋“ค์€ ๋””์Šคํฌ์—์„œ ์‹คํ–‰๊ณผ ๋™์‹œ์— ์šด์˜์ฒด์ œ์— ์˜ํ•ด ํ”„๋กœ๊ทธ๋žจ์„ ๋ฉ”๋ชจ๋ฆฌ๋กœ ๊ฐ€์ง€๊ณ ์™€์„œ ํ”„๋กœ๊ทธ๋žจ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํ”„๋กœ์„ธ์Šค๋Š” ๋…๋ฆฝ์ ์ด๋ฉฐ ๋‚ด๋ถ€๋Š” PID, Code, Heap Data, Files, ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๋กœ ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ ์™ธ์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ ๋™์ž‘ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค์ธ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ๋Š” ์Šคํ…์„ ๊ฐ€์ง€๋Š”๋ฐ ์ง€์—ญ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ณ , instruction pointer๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ๋‹ค์Œ ๋ช…๋ น์–ด ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ”„๋กœ์„ธ์Šค์˜ ๊ตฌ์กฐ ์ถ”๊ฐ€์กฐ์‚ฌ
    • ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ๋ฆฌํ„ด๋  ์ฃผ์†Œ๊ฐ€ ์Šคํ…์ด ์ €์žฅ๋˜๊ณ  ์ง€์—ญ ๋ณ€์ˆ˜๋“ค๋„ ์ฐจ๋ก€๋กœ ์Šคํƒ์— ์Œ“์ด๋Š”๋ฐ, ํ•จ์ˆ˜ ์‹คํ–‰ ํ›„์—๋Š” ์Šคํƒ ๋ฐ์ดํ„ฐ๋“ค์ด ์ฐจ๋ก€๋กœ ์‚ฌ๋ผ์ง€๊ณ  ๋ฆฌํ„ด๋  ์ฃผ์†Œ๋„ ์ง€์›์ง€๊ณ  ๋ฆฌํ„ด๋  ๊ณณ์œผ๋กœ ์ด๋™๋ฉ๋‹ˆ๋‹ค.
    • ์Šคํƒ ํ”„๋ ˆ์ž„
  • ํ”„๋กœ์„ธ์Šค ์ƒํƒœ์™€ ๊ณ„์ธต๊ตฌ์กฐ
    • ํ”„๋กœ์„ธ์Šค์˜ ์ƒํƒœ๋ฅผ PCB์— ๊ธฐ๋กํ•ด์„œ ๊ด€๋ฆฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜๋งŽ์€ ํ”„๋กœ์„ธ์Šค๋ฅผ ๊ณ„์ธต์ ์œผ๋กœ ๊ด€๋ฆฌ, ์šด์˜์ฒด์ œ ๋งˆ๋‹ค ํ”„๋กœ์„ธ์Šค ์ƒํƒœ๋Š” 5๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค. ์ƒ์„ฑ, ์ค€๋น„, ์‹คํ–‰, ๋Œ€๊ธฐ(blocked status), ์ข…๋ฃŒ ์ƒํƒœ
    • ๋ถ€๋ชจ ํ”„๋กœ์„ธ์Šค๋Š” fork ์‹œ์Šคํ…œ ํ˜ธ์ถœ๋กœ ์ž์‹ ์˜ ๋ณต์‚ฌ๋ณธ ์ž์‹ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ƒ์„ฑ, ์ž์› ์ƒ์†
    • ์ž์‹ ํ”„๋กœ์„ธ์Šค๋Š” exec ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์„ ์ƒˆ๋กœ์šด ํ”„๋กœ๊ทธ๋žจ์„ ๋ฎ์–ด์“ฐ๊ธฐ, ์ฝ”๋“œ/๋ฐ์ดํ„ฐ ์˜์—ญ์€ ์‹คํ–‰ํ•  ํ”„๋กœ๊ทธ๋žจ ๋‚ด์šฉ์œผ๋กœ ๋ฐ”๋€Œ๊ณ  ๋‚˜๋จธ์ง€ ์˜์—ญ์€ ์ดˆ๊ธฐํ™”

ํ˜ผ์ž ๊ณต๋ถ€ํ•˜๋Š” ์ปดํ“จํ„ฐ ๊ตฌ์กฐ ์šด์˜์ฒด์ œ ํ•œ๋น› ๋ฏธ๋””์–ด ๊ฐ•์˜๋ฅผ ๋‹ค ๋“ค์–ด๋ณด๋Š” ๊ฒƒ๋„ ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค..!

์ปจํ…์ŠคํŠธ ์Šค์œ„์น˜

๋™์‹œ์— ๋งŽ์€ ์Šค๋ ˆ๋“œ๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ฒƒ์€ ์‰ฝ์ง€ ์•Š๋‹ค. ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ ์ „ํ™˜ํ•  ๋•Œ๋Š” ๊ธฐ์กด์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ cpu์— ๋ณต์›ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ์Šค์ผ€์ฅด๋ง

๊ธฐ์•„ํ˜„์ƒ์ด ๋ฐœ์ƒ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์šด์˜์ฒด์ œ๊ฐ€ cpu์— ์Šค๋ ˆ๋“œ๋ฅผ ๊ณตํ‰ํ•˜๊ฒŒ ๋ฐฐ์น˜ํ•  ๋•Œ๋Š” ์—ฌ๋Ÿฌ ๋ฌธ์ œ์ ๋“ค์„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šด์˜์ฒด์ œ๋Š” ์—ํฌํฌ์— ๋งž์ถฐ ์‹œ๊ฐ„์„ ์ ๋‹นํ•œ ํฌ๊ธฐ๋กœ ๋‚˜๋ˆ•๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์Šค๋ ˆ๋“œ์˜ ํƒ€์ž„ ์Šฌ๋ผ์ด์Šค๋ฅผ ์ข…๋ฅ˜๋ณ„๋กœ ์—ํฌํฌ์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค.
์Šค๋ ˆ๋“œ์— ์‹œ๊ฐ„์„ ํ• ๋‹นํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ์šด์˜์ฒด์ œ๊ฐ€ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋‹ฌ๋ ค์žˆ์Šต๋‹ˆ๋‹ค. ์ธํ„ฐ๋ ‰ํ‹ฐ๋ธŒํ•œ ์Šค๋ ˆ๋“œ์— ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‘๊ณ , ์Šค๋ ˆ๋“œ ์ž์ฒด๋Š” ์ƒ์„ฑ๊ณผ ํŒŒ๊ดด๊ฐ€ ํ›จ์”ฌ ์‰ฝ๊ณ  ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ์•ˆ์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ณ‘ํ–‰์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋ฉด ๋” ๋น ๋ฅด๊ณ  ํšจ๊ณผ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ณด์•ˆ๊ณผ ์•ˆ์ „์„ฑ์„ ์œ„ํ•ด์„œ๋Š” ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.



2. ์Šค๋ ˆ๋”ฉ ๊ธฐ์ดˆ - ์Šค๋ ˆ๋“œ ์ƒ์„ฑ

์Šค๋ ˆ๋“œ ๊ธฐ๋Šฅ๊ณผ ๋””๋ฒ„๊น…

Runnable ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•ด์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์Šค๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•˜๋Š” ๊ฒƒ ์™ธ์—๋„ ์ด ์Šค๋ ˆ๋“œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋„ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ณ„์† ์†Œ๋น„ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šค๋ ˆ๋“œ๋ฅผ ๋ฐ”๋ฅด๊ฒŒ ๊ด€๋ฆฌํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ •๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๊ณ ๋ฏผํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            Thread.currentThread().getName();
        }
    });
    thread.setName("New Worker Thread");
    thread.setPriority(Thread.MAX_PRIOPITY);
    
    Thread.currentThread().getName();
    thread.start();
    Thread.currentThread().getName();
    
    Thread.sleep(1000);
}
public static void main(String[] args) throws InterruptedException {
    Thread thread = new Thread(new Runnable(){
        @Override
        public void run() {
            throw new RuntimeExcpetion("Intentional Exception");
        }
    });
    
    thread.setName("Misbehaving thread");
    
    thread.setUncaughtExceptionHandler(new Thread.UncaughtExcpetionHandler() {
        @Override
        public void uncaughtException(Thread t, Throuable e) { 
            t.getName();
            e.getMessage();
        }
    })
}
์Šค๋ ˆ๋“œ ์ƒ์†
public static void main(String[] args) throws InterruptedException {
    Thread thread = new NewThread();
    thread.start();
}

private static class NewThread extends Thread {
    @Override
    public void run() {
        Thread.currentThread().getName();
    }
}

Quiz

ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์— ์†ํ•œ ๋‹ค์ˆ˜์˜ ์Šค๋ ˆ๋“œ๋Š” ๋‹ค์Œ ํ•ญ๋ชฉ์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค.

  • ํž™
  • ์ฝ”๋“œ
  • ํ”„๋กœ์„ธ์Šค์˜ ์—ด๋ฆฐ ํŒŒ์ผ
  • ํ”„๋กœ์„ธ์Šค์˜ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ
Thread thread = new Thread(new Runnable() {
  @Override
  public void run() {
     System.out.println("Executing from a new thread");
  }
});

์ด ์ฝ”๋“œ์—๋Š” ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  thread.start() ํ˜ธ์ถœ์„ ํ†ตํ•ด ์‹œ์ž‘๋  ๊ฒฝ์šฐ, ์ƒˆ ์Šค๋ ˆ๋“œ์˜ run() ๋ฉ”์„œ๋“œ ์•ˆ์— ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์ฝ”๋”ฉ ์—ฐ์Šต 1: ์Šค๋ ˆ๋“œ ์ƒ์„ฑ - MultiExecutor
import java.util.*;

public class MultiExecutor {

    public MultiExecutor(List<Runnable> tasks) {
        for(Runnable thread:tasks){
            thread.run();
        }
    }

    public void executeAll() {
        Thread thread1 = new Thread("thread1");
        Thread thread2 = new Thread("thread2");
        List<Runnable> list = new ArrayList();
        list.add(thread1);
        list.add(thread2);
        new MultiExecutor(list);
    }
}
์ฝ”๋”ฉ ์—ฐ์Šต 2: ์Šค๋ ˆ๋“œ ์ƒ์„ฑ - MultiExecutor ์†”๋ฃจ์…˜
import java.util.ArrayList;
import java.util.List;
 
public class MultiExecutor {
    
    private final List<Runnable> tasks;
 
    /*
     * @param tasks to executed concurrently
     */
    public MultiExecutor(List<Runnable> tasks) {
        this.tasks = tasks;
    }
 
    /**
     * Executes all the tasks concurrently
     */
    public void executeAll() {
        List<Thread> threads = new ArrayList<>(tasks.size());
        
        for (Runnable task : tasks) {
            Thread thread = new Thread(task);
            threads.add(thread);
        }
        
        for(Thread thread : threads) {
            thread.start();
        }
    }
}
  • ์ œ๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์™€ ๋น„๊ตํ–ˆ์„ ๋•Œ ์†”๋ฃจ์…˜์ด ๋” ์ข‹๋‹ค๊ณ  ๋Š๋‚€ ์ ์ด ๋งŽ์•˜๋Š”๋ฐ, ์ผ๋‹จ ํด๋ž˜์Šค์—์„œ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž ํ˜ธ์ถœ์„ ๊ทธ ํด๋ž˜์Šค ๋‚ด์˜ ๋ฉ”์„œ๋“œ์—์„œ new MultiExecutor(list);์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ํ‘œํ˜„ํ•˜๋Š”๊ฒŒ ๋ถ€์ ์ ˆํ•œ ๊ฒƒ ๊ฐ™์•˜์Šต๋‹ˆ๋‹ค.
  • ์†”๋ฃจ์…˜์—์„œ์˜ ํ•ด๋‹ต์ฒ˜๋Ÿผ private final List<Runnable> tasks; ํด๋ž˜์Šค ๋‚ด ๋ณ„๋„ ์ง€์—ญ ๋ณ€์ˆ˜๋ฅผ ๋‘๊ณ  ๊ทธ ๋ณ€์ˆ˜๋ฅผ ํ™œ์šฉํ•ด์„œ ๋ฉ”์„œ๋“œ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.



3. ์Šค๋ ˆ๋“œ ์กฐ์ •

์Šค๋ ˆ๋“œ๋ฅผ ์กฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด Thread.interrupt();๋ฅผ ์ด์šฉํ•œ ์ฒ˜๋ฆฌ๋ฅผ ๋งํ•ด์ฃผ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๊ฒƒ๋งŒ ๊ฐ€์ง€๊ณ  ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ํ–‰ํ•  ๋ฐฉ๋ฒ•์ด ์—†๋‹ค๋ฉด ์Šค๋ ˆ๋“œ๋ฅผ ๋ฉˆ์ถ”์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Thread.currentThread().isInterrupted()๋กœ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค interrupt ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด์„œ ์ฒดํ‚นํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๊ฐœ๋ณ„ ์ฒดํ‚นํ•˜๋Š” ๋ฐฉ์‹๋ง๊ณ  ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ์š”? Daemon Thread๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ(๋ฉ”์ธ์Šค๋ ˆ๋“œ์˜ ์ข…๋ฃŒ)์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋™์ž‘ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋Š” ์Šค๋ ˆ๋“œ์ž…๋‹ˆ๋‹ค. thread.setDaemon(true);์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ Daemon Thread์˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ์ˆ˜ํ–‰๋œ ํ›„ ๋ฉ”์ธ์Šค๋ ˆ๋“œ๊ฐ€ ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ๋„๋ก Thread.join()์„ ์ด์šฉํ•œ ์Šค๋ ˆ๋“œ ๋ณ‘๋ ฌ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์„ ์ƒ๊ฐํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// ์Šค๋ ˆ๋“œ๊ฐ€ interrupt๋œ ๊ฒฝ์šฐ InterruptedException ์‚ฌ๋ก€
@Override
public void run() {
  try {
    Thread.sleep(500000);
  } catch (InterruptedException e) {
    System.out.println("Existing blocking thread");
  }
}
// ์Šค๋ ˆ๋“œ์˜ interrupt ์—ฌ๋ถ€๋ฅผ checking ๋ฐฉ์‹
for (BigInteger i = BigInteger.ZERO; i.compareTo(power) != 0; i = i.add(BigInteger.ONE)) {
  if (Thread.currentThread().isInterrupted()) {
    System.out.println("Prematurely interrupted computation");
    return BigInteger.ZERO;
  }
  result = result.multiply(base);
}
// Daemon Thread์˜ ์ ์šฉ
thread.setDaemon(true);



4. ์„ฑ๋Šฅ ์ตœ์ ํ™”

์—ฌ๊ธฐ์„œ ๋งํ•˜๋Š” ์„ฑ๋Šฅ์€ Latency ์ง€์—ฐ์‹œ๊ฐ„๊ณผ Throughput ์ฒ˜๋ฆฌ๋Ÿ‰์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€์—ฐ์‹œ๊ฐ„

CPU 1์ฝ”์–ด ๋‹น ํ•˜๋‚˜์˜ task๋งŒ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฐฐ์น˜๋˜์–ด ์žˆ๊ณ  ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ์ถ”๊ฐ€๋œ ๊ฒฝ์šฐ(์ฆ‰ ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๋งŽ์•„์ง„ ๊ฒฝ์šฐ), ์ผ๋ฐ˜์ ์œผ๋กœ ์ปจํ…์ŠคํŠธ ์Šค์œ„์นญ๊ณผ ์บ์‹œ ์„ฑ๋Šฅ ์ €ํ•˜๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ตœ์ ์˜ ์ƒํƒœ๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ Runnableํ•œ ์ƒํƒœ๋ผ๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ•์˜์—๋Š” ์‚ฌ๋ก€๋กœ thread๋ฅผ ์ด์šฉํ•œ ์ง€์—ฐ์‹œ๊ฐ„์„ ์ค„์ด๋Š” ์ด๋ฏธ์ง€ ํ”„๋กœ์„ธ์‹ฑ์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ๋‹ด๊ณ  ์žˆ์—ˆ๋Š”๋ฐ, ๋ง‰ ๋ณต์žกํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ์ด๋ฏธ์ง€ ๋ณ€ํ™”๋ฅผ ์‹ค์ œ๋กœ ๋ณผ ์ˆ˜ ์žˆ์–ด์„œ ํฅ๋ฏธ๋กœ์› ์Šต๋‹ˆ๋‹ค.

๋จผ์ € RGB ์ƒ‰์„ ๋ฝ‘์•„๋‚ด๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ๊ฐ ๋น„ํŠธ ์ž๋ฆฌ์˜ FF ์œ„์น˜์— ๋”ฐ๋ผ ํ”ฝ์…€ ์ƒ‰์ƒ ์ธ์ฝ”๋”ฉ ๊ทธ๋ฃน ์ค‘ ํ•˜๋‚˜์ธ RGB ์ƒ‰์ƒ์„ ๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ๊ณ ๋กœ ARGB๋ผ๊ณ  ํ‘œํ˜„ํ–ˆ์„ ๋•Œ๋Š” RGB ๋ฐฉ์‹์˜ ํ•œ ๋ฒ„์ „์œผ๋กœ, ์—ฌ๊ธฐ์„œ A๋Š” alpha, ์ฆ‰, ์•ŒํŒŒ(ํˆฌ๋ช…๋„)๋ฅผ ๋œปํ•ฉ๋‹ˆ๋‹ค. ๋น„ํŠธ๋งˆ์Šคํฌ์˜ ๊ฒฐ๊ณผ๊ฐ’์— ์žˆ๋Š” ๋ชจ๋“  ๋น„ํŠธ๋ฅผ >> ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•ด ์˜ค๋ฅธ์ชฝ์œผ๋กœ ์‹œํ”„ํŠธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    public static int getRed(int rgb) {
        return (rgb & 0x00FF0000) >> 16;
    }

    public static int getGreen(int rgb) {
        return (rgb & 0x0000FF00) >> 8;
    }

    public static int getBlue(int rgb) {
        return rgb & 0x000000FF;
    }

๊ฐ•์˜์—์„œ๋Š” ํฐ๊ฝƒ์„ ๋ชจ๋‘ ๋ถ„ํ™์ƒ‰ ๊ฝƒ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ด๋ฏธ์ง€ ํ”„๋กœ์„ธ์‹ฑ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ–ˆ๋Š”๋ฐ, ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์ด๋ฏธ์ง€ ๋†’์ด๋ฅผ ์Šค๋ ˆ๋“œ ์ˆ˜๋กœ ๋‚˜๋ˆ  ๊ฐ๊ฐ ์Šค๋ ˆ๋“œ๊ฐ€ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ์Šค๋ ˆ๋“œ ์ˆ˜๋ฅผ ๊ฐ€์ƒ ์ฝ”์–ด ์ˆ˜๋ณด๋‹ค ๋งŽ๊ฒŒ ๋Š˜๋ฆฌ๋ฉด ๋ฒ ๋„คํ•์ด ์—†์Šต๋‹ˆ๋‹ค.
  • ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณ‘๋ ฌ ์‹คํ–‰์—๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“ญ๋‹ˆ๋‹ค.
    public static void recolorImage(BufferedImage originalImage, BufferedImage resultImage, int leftCorner, int topCorner, int width, int height) {
      for(int x = leftCorner ; x < leftCorner + width && x < originalImage.getWidth() ; x++) {
          for(int y = topCorner ; y < topCorner + height && y < originalImage.getHeight() ; y++) {
              recolorPixel(originalImage, resultImage, x , y);
          }
      }
    }
    
์ฒ˜๋ฆฌ๋Ÿ‰

์ฒ˜๋ฆฌ๋Ÿ‰์€ ์ž‘์—…๋Ÿ‰์„ ์Šค๋ ˆ๋“œ๋กœ ๋‚˜๋ˆˆ ๊ฐ’(T/N)์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ Task๋ฅผ ๋‚˜๋ˆ„๊ณ  ํ•ฉ์น˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ ๋น„์šฉ์ด ๋ฐœ์ƒํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ„์— ๋ณ„๋„ ์Šค๋ ˆ๋“œ๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์˜คํžˆ๋ ค ๋” ์„ฑ๋Šฅ์ด ์ข‹์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์Šค๋ ˆ๋“œ ์ˆ˜๊ฐ€ ๋” ๋งŽ์•„์ง€๋ฉด ๊ทธ ์ฒ˜๋ฆฌ๋Ÿ‰์—์„œ ์ฒ˜๋ฆฌ๊ฐ€ ๋‚˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ์ • ์ˆ˜ ์ด์ƒ์˜ ์Šค๋ ˆ๋“œ์—์„œ๋Š” ์„ฑ๋Šฅ์ด ๋” ์ข‹๊ฒŒ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



5. ์Šค๋ ˆ๋“œ ๊ฐ„ ๋ฐ์ดํ„ฐ ๊ณต์œ 

์Šคํƒ๊ณผ ํž™

์Šคํƒ์€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋ฉ”์„œ๋“œ๊ฐ€ ํ›„์ž…์„ ์ถœ๋กœ ์‹คํ–‰๋˜๋Š” ๊ณต๊ฐ„์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์Šคํƒ์—๋Š” Local primitive types, Local references๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ํž™์€ JVM์—์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ณต๊ฐ„์œผ๋กœ Objects, Class Members, Static valuables๋ฅผ ๋‹ด๋Š” ๊ณต๊ฐ„์ž…๋‹ˆ๋‹ค.

์›์ž์ น ์ž‘์—…, Atomic Operations

์›์ž์  ์ž‘์—…์ด๋ž€ ๋ง๊ทธ๋Œ€๋กœ ํ•˜๋‚˜์˜ ์›์ž์™€ ๊ฐ™์ด ์ž‘์—… ์ž์ฒด๊ฐ€ ํ•œ ๋ฒˆ์— ์‹คํ–‰๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ๋งํ•ฉ๋‹ˆ๋‹ค.
items++;๋Š” ์›์ž์  ์ž‘์—…์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์—†๋Š”๋ฐ ๊ทธ ์ด์œ ๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ˜„์žฌ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์˜ค๊ณ , ๊ทธ ๋‹ค์Œ ๊ทธ ๊ฐ’์— 1์„ ๋”ํ•˜๊ณ , ๊ทธ new Value๋ฅผ items์— ๋Œ€์ž…ํ•˜๋Š” ์‹์œผ๋กœ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.



6. ๋ณ‘ํ–‰์„ฑ ๋ฌธ์ œ์™€ ์†”๋ฃจ์…˜

์ž„๊ณ„์˜์—ญ๊ณผ ๋™๊ธฐํ™”

์ž„๊ณ„์˜์—ญ์ด๋ž€ ํ•˜๋‚˜์˜ ์›์ž์„ฑ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋Š” ์˜์—ญ์„ ๋งํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜์—ญ์ด ํ•˜๋‚˜์˜ ์›์ž์„ฑ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด์„œ java์—์„œ๋Š” ๋ฉ”์„œ๋“œ์— synchronized ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„ ์›์ž์„ฑ ์ž‘์—…์€ get, sest, refercences์™€ ๊ฐ™์€ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋Œ€๋ถ€๋ถ„์˜ ๋ฉ”์„œ๋“œ๋Š” ๋น„์›์ž์  ์ž‘์—…์œผ๋กœ ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™๊ธฐํ™”์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ณ€์ˆ˜์—๋„ volatile ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•ด ์›์ž์„ฑ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ long, double๊ณผ ๊ฐ™์€ ๋ณ€์ˆ˜๋“ค์€ 64bit ์ž๋ฐ”์—์„œ ๋ณด์žฅ๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— 32bit๋กœ ๋‚˜๋ˆ ์„œ ์ฒ˜๋ฆฌ๋˜๋Š” ๊ณผ์ •์—์„œ ์›์ž์„ฑ์ด ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

private static class InventoryCounter {
  private int items = 0;
  Object lock = new Object();
  public void increment() {
    synchronized (this.lock) {
        items++;
    }
  }
  // ...
}
๊ฒฝ์Ÿ ์ƒํƒœ ๋ฐ ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ, ๋ฝํ‚น ๊ธฐ๋ฒ•๊ณผ ๋ฐ๋“œ๋ฝ

๋ง ๊ทธ๋Œ€๋กœ ๊ฒฝํ•ฉ ์ƒํƒœ์™€ ๋™๊ธฐ์„ฑ ๋ฌธ์ œ๋กœ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ์œผ๋กœ ๊ณต์œ  ๋ฆฌ์†Œ์Šค์— ๋น„์›์ž์  ์—ฐ์‚ฐ์ด ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๊ฒฝ์Ÿ์ƒํƒœ ์ง€์ ์ธ ์ž„๊ณ„์˜์—ญ์„ ๋™๊ธฐํ™” ๋ธ”๋ก์— ๋„ฃ์–ด ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ๊ฒฝ์Ÿ์ƒํƒœ์—์„œ deadlock์ด ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜๋Š”๋ฐ ์ƒํ˜ธ๋ฐฐ์ œ, hold and wait, ๋น„์„ ์ , ์ˆœํ™˜๋Œ€๊ธฐ ๋ฌธ์ œ๋ฅผ ๋ชจ๋‘ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์ˆœํ™˜๋Œ€๊ธฐ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ๋ชจ๋“  ๋ฉ”์„œ๋“œ์— ์ ‘๊ทผ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ฐฉ์•ˆ์„ ํ•ด๊ฒฐ๋ฒ•์œผ๋กœ ์ œ์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์€ ๋น„์ˆœ์ฐจ์  ์‹คํ–‰์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆœ์ฐจ์  ๊ณ„์‚ฐ์ด ์•„๋‹Œ ๊ฐ’์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ˜์˜์œผ๋กœ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ๋งํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ์—์„œ increment()์—์„œ x++;, y++; ๋ชจ๋‘ ์›์ž์  ์ž‘์—…์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฒ˜๋ฆฌ ์ดํ›„์— checkForDataRace()๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด ๋ฐ์ดํ„ฐ ๊ฒฝ์Ÿ์ด ๋ฐœ์ƒํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

public class Main {
  public static void main(String[] args) {
    SharedClass sharedClass = new SharedClass();
    Thread thread1 = new Thread(() -> {
      for (int i = 0; i < Integer.MAX_VALUE; i++) {
        sharedClass.increment();
      }
    });

    Thread thread2 = new Thread(() -> {
      for (int i = 0; i < Integer.MAX_VALUE; i++) {
        sharedClass.checkForDataRace();
      }

    });

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

  public static class SharedClass {
    private int x = 0;
    private int y = 0;

    public void increment() {
      x++;
      y++;
    }

    public void checkForDataRace() {
      if (y > x) {
        System.out.println("y > x - Data Race is detected");
      }
    }
  }
}



7. ๋ฝํ‚น ์‹ฌํ™”

ReentrantLock์€ ์ž๋ฐ”์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ฐœ๋…์œผ๋กœ ๋ฝ์˜ ๊ณต์ •์„ฑ์„ ์ œ์–ดํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ์ฃผ๋กœ ์ฝ๊ธฐ ์ž‘์—…์„ ํ•˜๊ณ  ์“ฐ๊ธฐ ์ž‘์—…์ด ์ ์€ ๊ฒฝ์šฐ์—๋Š” ReentrantReadWriteLock์„ ์‚ฌ์šฉํ•ด์„œ ๊ณต์œ ์ž์›์„ ๋™์‹œ์— ์ฝ๋Š” ๊ฒƒ์„ ํ—ˆ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

private ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
private Lock readLock = reentrantReadWriteLock.readLock();
private Lock writeLock = reentrantReadWriteLock.writeLock();

public int getNumberOfItemsInPriceRange(int lowerBound, int upperBound) {
  readLock.lock();
  try {
    Integer fromKey = priceToCountMap.ceilingKey(lowerBound);
    Integer toKey = priceToCountMap.floorKey(upperBound);
    if (fromKey == null || toKey == null) {
        return 0;
    }
    NavigableMap<Integer, Integer> rangeOfPrices = priceToCountMap.subMap(fromKey, true, toKey, true);
    int sum = 0;
    for (int numberOfItemsForPrice : rangeOfPrices.values()) {
        sum += numberOfItemsForPrice;
    }
	
    return sum;
  } finally {
    readLock.unlock();
  }
}

results matching ""

    No results matching ""