Java

[Effective Java] ์•„์ดํ…œ 79. ๊ณผ๋„ํ•œ ๋™๊ธฐํ™”๋Š” ํ”ผํ•˜๋ผ.

quedevel 2023. 4. 13. 14:49
728x90
๋ฐ˜์‘ํ˜•

๐ŸŽฏ ์•„์ดํ…œ 79. ๊ณผ๋„ํ•œ ๋™๊ธฐํ™”๋Š” ํ”ผํ•˜๋ผ.

์‘๋‹ต ๋ถˆ๊ฐ€์™€ ์•ˆ์ „ ์‹คํŒจ๋ฅผ ํ”ผํ•˜๋ ค๋ฉด ๋™๊ธฐํ™” ๋ฉ”์„œ๋“œ๋‚˜ ๋™๊ธฐํ™” ๋ธ”๋ก ์•ˆ์—์„œ๋Š” ์ œ์–ด๋ฅผ ์ ˆ๋Œ€๋กœ ํด๋ผ์ด์–ธํŠธ์— ์–‘๋„ํ•˜๋ฉด ์•ˆ๋œ๋‹ค. ๋™๊ธฐํ™”๋œ ์˜์—ญ์„ ํฌํ•จํ•œ ํด๋ž˜์Šค ๊ด€์ ์—์„œ๋Š” ์ด๋Ÿฐ ๋ฉ”์„œ๋“œ๋Š” ๋ชจ๋‘ ๋ฐ”๊นฅ ์„ธ์ƒ์—์„œ ์˜จ ์™ธ๊ณ„์ธ์ด๋ฏ€๋กœ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๋Š” ์ด์Šˆ๋ฅผ ๋ฐœ์ƒ ์‹œํ‚จ๋‹ค

  • ์ž˜๋ชป๋œ ์ฝ”๋“œ. ๋™๊ธฐํ™” ๋ธ”๋ก ์•ˆ์—์„œ ์™ธ๊ณ„์ธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
public class ObservableSet<E> extends ForwardingSet<E> {
    public ObservableSet(Set<E> set) { super(set); }

    private final List<SetObserver<E>> observers = new ArrayList<>();

    public void addObserver(SetObserver<E> observer) {
        synchronized(observers) {
            observers.add(observer);
        }
    }

    public boolean removeObserver(SetObserver<E> observer) {
        synchronized(observers) {
            return observers.remove(observer);
        }
    }

    private void notifyElementAdded(E element) {
        synchronized(observers) {
            for (SetObserver<E> observer : observers)
                observer.added(this, element);
        }
    }

    @Override 
    public boolean add(E element) {
        boolean added = super.add(element);
        if (added)
            notifyElementAdded(element);
        return added;
    }
}
public static void main(String[] args) {
    ObservableSet<Integer> set = new ObservableSet<>(new HashSet<>());

    set.addObserver(new SetObserver<>() {
        public void added(ObservableSet<Integer> s, Integer e) {
            System.out.println(e);
            if (e == 23) // ๊ฐ’์ด 23์ด๋ฉด ์ž์‹ ์„ ๊ตฌ๋…ํ•ด์ง€ํ•œ๋‹ค.
                s.removeObserver(this);
        }
    });

    for (int i = 0; i < 100; i++)
        set.add(i);
}

์ด ํ”„๋กœ๊ทธ๋žจ์€ 23๊นŒ์ง€ ์ถœ๋ ฅํ•œ ๋‹ค์Œ ConcurrentModificationException์„ ๋˜์ง„๋‹ค. added ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด ์ผ์–ด๋‚œ ์‹œ์ ์ด notifyElementAdded๊ฐ€ ๊ด€์ฐฐ์ž๋“ค์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆœํšŒํ•˜๋Š” ๋„์ค‘์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

  • ์“ธ๋ฐ์—†์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ด€์ฐฐ์ž
public static void main(String[] args) {
    ObservableSet<Integer> set = new ObservableSet<>(new HashSet<>());

    set.addObserver(new SetObserver<>() {
        public void added(ObservableSet<Integer> s, Integer e) {
            System.out.println(e);
            if (e == 23) {
                ExecutorService exec = Executors.newSingleThreadExecutor();
                try {
                    exec.submit(() -> s.removeObserver(this)).get();
                } catch (ExecutionException | InterruptedException ex) {
                    throw new AssertionError(ex);
                } finally {
                    exec.shutdown();
                }
            }
        }
    });

    for (int i = 0; i < 100; i++)
        set.add(i);
}

์ด ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰ํ•˜๋ฉด ์˜ˆ์™ธ๋Š” ๋‚˜์ง€ ์•Š์ง€๋งŒ ๊ต์ฐฉ์ƒํƒœ์— ๋น ์ง„๋‹ค.

  • ํ•ด๊ฒฐ์ฑ… 1 ์™ธ๊ณ„์ธ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์„ ๋™๊ธฐํ™” ๋ธ”๋ก ๋ฐ”๊นฅ์œผ๋กœ ์˜ฎ๊ธด๋‹ค.
private void notifyElementAdded(E element) {
    List<SetObserver<E>> snapshot = null;
    synchronized(observers) {
        snapshot = new ArrayList<>(observers);
    }
    for (SetObserver<E> observer : snapshot)
        observer.added(this, element);
}

  • ํ•ด๊ฒฐ์ฑ… 2 CopyOnWriteArrayList๋ฅผ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•œ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๊ณ  ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ์ง‘ํ•ฉ
private final List<SetObserver<E>> observers = new CopyOnWriteArrayList<>();

๊ธฐ๋ณธ ๊ทœ์น™์€ ๋™๊ธฐํ™” ์˜์—ญ์—์„œ๋Š” ๊ฐ€๋Šฅํ•œ ํ•œ ์ผ์„ ์ ๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

  • ๊ฐ€๋ณ€ ํด๋ž˜์Šค๋ฅผ ์ž‘์„ฑํ•˜๋ ค๊ฑฐ๋“  ๋‹ค์Œ ๋‘ ์„ ํƒ์ง€ ์ค‘ ํ•˜๋‚˜๋ฅผ ๋”ฐ๋ฅด์ž.

1.๋™๊ธฐํ™”๋ฅผ ํ•˜์ง€๋ง๊ณ , ํด๋ž˜์Šค๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ํด๋ž˜์Šค๊ฐ€ ์™ธ๋ถ€์—์„œ ๋™๊ธฐํ™”๋„๋ก ํ•˜์ž.

2.๋™๊ธฐํ™”๋ฅผ ๋‚ด๋ถ€์—์„œ ์ˆ˜ํ–‰ํ•ด ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค์ž.

1๏ธโƒฃ ๋ฝ ๋ถ„ํ• (lock splitting)

2๏ธโƒฃ ๋ฝ ์ŠคํŠธ๋ผ์ด์ดํ•‘(lock striping)

3๏ธโƒฃ ๋น„์ฐจ๋‹จ ๋™์‹œ์„ฑ ์ œ์–ด(nonblocking concurrency control)

์ฐธ๊ณ  ์ž๋ฃŒ

Joshua Bloch, ใ€ŽEffective Java 3/Eใ€, ๊ฐœ์•ž๋งต์‹œ ์˜ฎ๊น€, ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ธ์‚ฌ์ดํŠธ(2018)
http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966262281&orderClick=LEa&Kc=

728x90
๋ฐ˜์‘ํ˜•