[์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ”] Item8. finalizer์™€ cleaner ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ผ.

2023. 1. 22. 21:16ใ†JAVA/Effective JAVA

728x90

 

item08. finalizer์™€ cleaner ์‚ฌ์šฉ์„ ํ”ผํ•˜๋ผ. 

์ดํŽ™ํ‹ฐ๋ธŒ ์ž๋ฐ” part 1์—์„œ๋Š” ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์†Œ๋ฉธ์— ๋Œ€ํ•ด์„œ ์–˜๊ธฐํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์ง€๊ธˆ์€ ์ €๋ฒˆ item ๋ถ€ํ„ฐ๋Š” ๊ฐ์ฒด ์†Œ๋ฉธ์— ๋Œ€ํ•ด์„œ ์ด์•ผ๊ธฐ ํ•˜๊ณ  ์žˆ๋‹ค. 

์šฐ์„  ์ž๋ฐ”์—์„œ๋Š”  ๋‘ ๊ฐ€์ง€ ๊ฐ์ฒด ์†Œ๋ฉธ์ž๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

finalizer์™€ cleaner์ธ๋ฐ ๊ฒฐ๋ก ์„ ์–˜๊ธฐํ•˜์ž๋ฉด ๋‘˜๋‹ค ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. ์•„๋‹ˆ ๊ถŒ์žฅ์ด ์•„๋‹ˆ๋ผ ์ฑ…์—์„œ๋Š” ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๋ผ๊ณ  ํ•œ๋‹ค. (ํŠนํžˆ finalizer)

 

ํŠนํžˆ finalizer๋Š” ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๊ณ , ์ƒํ™ฉ์— ๋”ฐ๋ผ ์œ„ํ—˜ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ฐ˜์ ์œผ๋กœ ๋ถˆํ•„์š”ํ•˜๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ์˜ค๋™์ž‘, ๋‚ฎ์€ ์„ฑ๋Šฅ, ์ด์‹์„ฑ ๋ฌธ์ œ์˜ ์›์ธ์ด ๋˜๊ธฐ๋„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ๋ณธ์ ์œผ๋ก  ์“ฐ์ง€ ๋ง๋ผ๊ณ  ํ•œ๋‹ค.

ํŠนํžˆ java 9๋ถ€ํ„ฐ๋Š” deprecated ๋˜์–ด์„œ ๋Œ€์•ˆ์œผ๋กœ cleaner๋ฅผ ์†Œ๊ฐœํ•˜๊ณ  ์žˆ๋Š”๋ฐ cleaner๋Š” ๊ทธ๋‚˜๋งˆ finalizer๋ณด๋‹ค๋Š” ๋œ ์œ„ํ—˜ํ•˜์ง€๋งŒ, cleaner ์—ญ์‹œ ์˜ˆ์ธกํ•  ์ˆ˜ ์—†๊ณ , ๋Š๋ฆฌ๋ฉฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ถˆํ•„์š”ํ•˜๋‹ค. 

 

 

1๏ธโƒฃ finalizer์™€ cleaner๋Š” ์ฆ‰์‹œ ์ˆ˜ํ–‰๋œ๋‹ค๋Š” ๋ณด์žฅ์ด ์—†๋‹ค. 

finalizer์™€ cleaner๊ฐ€ ์‹คํ–‰๋˜๊ธฐ๊นŒ์ง€ ์–ผ๋งˆ๋‚˜ ๊ฑธ๋ฆฌ๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋•Œ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋Š” ์ž‘์—…์— ์ ˆ๋Œ€ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ๋œ๋‹ค.

 

ex) ํŒŒ์ผ ๋‹ซ๊ธฐ๋ฅผ finalizer ํ˜น์€ cleaner์— ๋งก๊ธฐ๋ฉด ์ค‘๋Œ€ํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. 

-> ์‹œ์Šคํ…œ์ด ๋™์‹œ์— ์—ด ์ˆ˜ ์žˆ๋Š” ํŒŒ์ผ ๊ฐœ์ˆ˜์—๋Š” ํ•œ๊ณ„๊ฐ€ ์žˆ๋Š”๋ฐ finalizer๋‚˜ cleaner๊ฐ€ ํŒŒ์ผ ๋‹ซ๊ธฐ๋ฅผ ์ฆ‰์‹œ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์•„์„œ ํŒŒ์ผ์„ ๊ณ„์† ์—ด์–ด ๋‘”๋‹ค๋ฉด ์ƒˆ๋กœ์šด ํŒŒ์ผ์œผ ์—ด์ง€ ๋ชปํ•ด์„œ ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํŒจํ•˜๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

2๏ธโƒฃ finalizer๋‚˜ cleaner ์ˆ˜ํ–‰ ์‹œ์ ๋ฟ ์•„๋‹ˆ๋ผ ์ˆ˜ํ–‰ ์—ฌ๋ถ€์กฐ์ฐจ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค. 

์ด ๋ง์€ ์ฆ‰ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” ์ผ๋ถ€ ๊ฐ์ฒด์— ๋”ธ๋ฆฐ ์ข…๋ฃŒ ์ž‘์—…์„ ์ „ํ˜€ ์ˆ˜ํ–‰ํ•˜์ง€ ๋ชปํ•œ ์ฑ„ ํ”„๋กœ๊ทธ๋žจ์ด ์ค‘๋‹จ๋  ์ˆ˜๋„ ์žˆ๋‹ค๋Š” ์ด์•ผ๊ธฐ์ด๋‹ค. 

๋”ฐ๋ผ์„œ ํ”„๋กœ๊ทธ๋žจ ์ƒ์•  ์ฃผ๊ธฐ์™€ ์ƒ๊ด€์—†๋Š”, ์ƒํƒœ๋ฅผ ์˜๊ตฌ์ ์œผ๋กœ ์ˆ˜์ •ํ•˜๋Š” ์ž‘์—…์—์„œ๋Š” ์ ˆ๋Œ€ finalizer, cleaner ์— ์˜์กดํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค. 

 

ex) ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฐ™์€ ๊ณต์œ  ์ž์›์˜ ์˜๊ตฌ ๋ฝ(lock) ํ•ด์ œ๋ฅผ finalizer ๋˜๋Š” cleaner์— ๋งก๊ธฐ๋ฉด ๋ถ„์‚ฐ ์‹œ์Šคํ…œ ์ „์ฒด๊ฐ€ ์„œ์„œํžˆ ๋ฉˆ์ถ”๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค..

 

 

 

3๏ธโƒฃ  finalizer ๋™์ž‘ ์ค‘ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋Š” ๋ฌด์‹œ๋˜๋ฉฐ, ์ฒ˜๋ฆฌํ•  ์ž‘์—…์ด ๋‚จ์•˜๋”๋ผ๋„ ๊ทธ ์ˆœ๊ฐ„ ์ข…๋ฃŒ๋œ๋‹ค. 

์žก์ง€ ๋ชปํ•œ ์˜ˆ์™ธ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๊ฐ์ฒด๋Š” ๋งˆ๋ฌด๋ฆฌ๊ฐ€ ๋œ ๋œ ์ƒํƒœ๋กœ ๋‚จ์„ ์ˆ˜๋„ ์žˆ๋‹ค. 

 

 

 

4๏ธโƒฃ finalizer์™€ cleaner๋Š” ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๋„ ๋™๋ฐ˜ํ•œ๋‹ค. 

 

 

 

5๏ธโƒฃ finalizer๋ฅผ ์‚ฌ์šฉํ•œ ํด๋ž˜์Šค๋Š” finalizer ๊ณต๊ฒฉ์— ๋…ธ์ถœ๋˜์–ด ์‹ฌ๊ฐํ•œ ๋ณด์•ˆ ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜๋„ ์žˆ๋‹ค. 

 

 

 

๐Ÿ’ก ๋Œ€์•ˆ

 

๋ฐ˜๋‚ฉํ•  ์ž์›์ด ์žˆ๋Š” ํด๋ž˜์Šค๋Š” AutoCloseable ์„ ๊ตฌํ˜„ํ•˜๊ณ  ํด๋ผ์ด์–ธํŠธ์—์„œ close()๋ฅผ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜
try-with-resource๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. 

 

 

AutoCloseable์„ ๊ตฌํ˜„ํ•ด์ฃผ๊ณ , ํด๋ผ์ด์–ธํŠธ์—์„œ ์ธ์Šคํ„ด์Šค๋ฅผ ๋‹ค ์“ฐ๊ณ  ๋‚˜๋ฉด close ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋œ๋‹ค. 

(์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ ์ œ๋Œ€๋กœ ์ข…๋ฃŒ๋˜๋„๋ก try-with-resource๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.) 

๊ทธ๋ฆฌ๊ณ  cleaner๋Š” ์•ˆ์ „๋ง์œผ๋กœ ์‚ฌ์šฉํ•ด ํ•˜๋‚˜์˜ ์ž์›์˜ ์†Œ์œ ์ž๊ฐ€ close๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์— ๋Œ€๋น„ํ•œ ์•ˆ์ „๋ง ์—ญํ• ์„ ํ•˜๊ฒŒ ํ•˜๋ฉด ๋œ๋‹ค. 

 

 

package chapter01.item08.cleaner_as_a_safetynet;

import java.lang.ref.Cleaner;

// cleaner๋ฅผ ์•ˆ์ „๋ง์œผ๋กœ ํ™œ์šฉํ•˜๋Š” AutoClosable ํด๋ž˜์Šค
public class Room implements AutoCloseable {
    private static final Cleaner cleaner = Cleaner.create();

    // ์ฒญ์†Œ๊ฐ€ ํ•„์š”ํ•œ ์ž์›, ์ ˆ๋Œ€ Room์„ ์ฐธ์กฐํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค!!
    private static class State implements Runnable {
        int numJunkPiles;

        State(int numJunkPiles) {
            this.numJunkPiles = numJunkPiles;
        }

        @Override
        public void run() {
            System.out.println("Cleaning room");
            numJunkPiles = 0;
        }
    }

    private final State state;

    private final Cleaner.Cleanable cleanable;

    public Room(int numJunkPiles) {
        state = new State(numJunkPiles);
        cleanable = cleaner.register(this, state);
    }


    @Override
    public void close()  {
        cleanable.clean();
    }
}

Room ํด๋ž˜์Šค๋Š” AutoCloseable์„ ๊ตฌํ˜„ํ•˜๊ณ , static์œผ๋กœ ์„ ์–ธ๋œ ์ค‘์ฒฉ ํด๋ž˜์Šค์ธ State๋Š” cleaner๊ฐ€ ๋ฐฉ์„ ์ฒญ์†Œํ•  ๋•Œ ์ˆ˜๊ฑฐํ•  ์ž์›๋“ค์„ ๋‹ด๊ณ  ์žˆ๋‹ค. 

State ํด๋ž˜์Šค๋Š” Runnable์„ ๊ตฌํ˜„ํ•˜๊ณ  ๊ทธ ์•ˆ์˜ run ๋ฉ”์„œ๋“œ๋Š” cleanable์— ์˜ํ•ด์„œ ๋”ฑ ํ•œ๋ฒˆ๋งŒ ํ˜ธ์ถœ๋  ๊ฒƒ์ด๋‹ค. 

์ด๋•Œ State ํด๋ž˜์Šค๋Š” ์ ˆ๋Œ€ Room ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•ด์„œ๋Š” ์•ˆ๋œ๋‹ค!! ์™œ๋ƒํ•˜๋ฉด Room ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐธ์กฐํ•  ๊ฒฝ์šฐ ์ˆœํ™˜์ฐธ์กฐ๊ฐ€ ์ƒ๊ธฐ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋น„์ง€  ์ปฌ๋ ‰ํ„ฐ๊ฐ€ Room ์ธ์Šคํ„ด์Šค๋ฅผ ํšŒ์ˆ˜ํ•ด ๊ฐˆ ๊ธฐํšŒ๊ฐ€ ์˜ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ์กฐํ•˜๋ฉด ์•ˆ๋œ๋‹ค. 

 

cleanable ๊ฐ์ฒด๋Š” Room ์ƒ์„ฑ์ž์—์„œ cleaner์— Room๊ณผ State๋ฅผ ๋“ฑ๋กํ•  ๋•Œ ์–ป๋Š”๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ  run ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ์ƒํ™ฉ์€ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋กœ ์ฒซ๋ฒˆ์งธ๋Š” Room์ด close ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ๋กœ close ๋ฉ”์„œ๋“œ์—์„œ cleanable ์˜ clean ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ด ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ run ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. 

 

๋‘๋ฒˆ์งธ๋กœ๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ Room์„ ํšŒ์ˆ˜ํ•  ๋•Œ๊นŒ์ง€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ clean์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด cleaner๊ฐ€ State์˜ run ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์ค„ ๊ฒƒ์ด๋‹ค. 

 

 

// cleaner ์•ˆ์ „๋ง์„ ๊ฐ–์ถ˜ ์ž์›์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ
public class Teenager {
    public static void main(String[] args) {
        new Room(99);
        System.out.println("Peace out");


        System.gc();
    }
}

์ฒซ๋ฒˆ์งธ Teenager ํด๋ž˜์Šค๋Š” Cleaner ์•ˆ์ „๋ง์„ ๊ฐ–์ถ˜ ์ž์›์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜์ง€ ๋ชปํ•œ ํด๋ผ์ด์–ธํŠธ๋กœ  clean์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•˜๋‹ค๊ฐ€ System.gc() ์ถ”๊ฐ€๋กœ ์ธํ•ด clenaer๊ฐ€ State์˜ run ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ "Cleaning room"์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜๋Š” ์žˆ์„ ๊ฒƒ์ด๋‹ค. 

 

// cleaner ์•ˆ์ „๋ง์„ ๊ฐ–์ถ˜ ์ž์›์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ
public class Adult {
    public static void main(String[] args) {
        try(Room myRoom = new Room(7)) {
            System.out.println("hi");
        }
    }
}

Audult ํด๋ž˜์Šค๋Š” cleaner ์•ˆ์ „๋ง์„ ๊ฐ–์ถ˜ ์ž์›์„ ์ œ๋Œ€๋กœ ํ™œ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ ๊ธฐ๋Œ€ํ•œ ๋Œ€๋กœ "hi"์™€ "Cleaning room"์ด ์ถœ๋ ฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

 

โœ๏ธ Room์˜ cleaner๋Š” ๋‹จ์ง€ ์•ˆ์ „๋ง์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ clean์„ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•˜์„ ๋•Œ๋ฅผ ๋Œ€๋น„ํ•ด์„œ ๋งŒ๋“  ๊ฒƒ์œผ๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ชจ๋“  Room ์ƒ์„ฑ์„ try-with-resource ๋ธ”๋ก์œผ๋กœ ๊ฐ์ŒŒ๋‹ค๋ฉด ์ž๋™ ์ฒญ์†Œ๋Š” ์ „ํ˜€ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค. 

 

 

 

 

 

 

 

 

 

728x90