#10 effective java: item 8
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.autocloseable;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try(AutoClosableIsGood good = new AutoClosableIsGood("")) {
|
||||||
|
// TODO 자원 반납 처리가 됨.
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.autocloseable;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class AutoClosableIsGood implements AutoCloseable {
|
||||||
|
|
||||||
|
private BufferedReader reader;
|
||||||
|
|
||||||
|
public AutoClosableIsGood(String path) {
|
||||||
|
try {
|
||||||
|
this.reader = new BufferedReader(new FileReader(path));
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
throw new IllegalArgumentException(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.cleaner;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class BigObject {
|
||||||
|
|
||||||
|
private List<Object> resource;
|
||||||
|
|
||||||
|
public BigObject(List<Object> resource) {
|
||||||
|
this.resource = resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ResourceCleaner implements Runnable {
|
||||||
|
|
||||||
|
private List<Object> resourceToClean;
|
||||||
|
|
||||||
|
public ResourceCleaner(List<Object> resourceToClean) {
|
||||||
|
this.resourceToClean = resourceToClean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
resourceToClean = null;
|
||||||
|
System.out.println("cleaned up.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.cleaner;
|
||||||
|
|
||||||
|
import java.lang.ref.Cleaner;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class CleanerIsNotGood {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
Cleaner cleaner = Cleaner.create();
|
||||||
|
|
||||||
|
List<Object> resourceToCleanUp = new ArrayList<>();
|
||||||
|
BigObject bigObject = new BigObject(resourceToCleanUp);
|
||||||
|
cleaner.register(bigObject, new BigObject.ResourceCleaner(resourceToCleanUp));
|
||||||
|
|
||||||
|
bigObject = null;
|
||||||
|
System.gc();
|
||||||
|
Thread.sleep(3000L);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.cleaner_as_a_safeynet;
|
||||||
|
|
||||||
|
// cleaner 안전망을 갖춘 자원을 제대로 활용하는 클라이언트 (45쪽)
|
||||||
|
public class Adult {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
try (Room myRoom = new Room(7)) {
|
||||||
|
System.out.println("안녕~");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.cleaner_as_a_safeynet;
|
||||||
|
|
||||||
|
import java.lang.ref.Cleaner;
|
||||||
|
|
||||||
|
// 코드 8-1 cleaner를 안전망으로 활용하는 AutoCloseable 클래스 (44쪽)
|
||||||
|
public class Room implements AutoCloseable {
|
||||||
|
private static final Cleaner cleaner = Cleaner.create();
|
||||||
|
|
||||||
|
// 청소가 필요한 자원. 절대 Room을 참조해서는 안 된다!
|
||||||
|
private static class State implements Runnable {
|
||||||
|
int numJunkPiles; // Number of junk piles in this room
|
||||||
|
|
||||||
|
State(int numJunkPiles) {
|
||||||
|
this.numJunkPiles = numJunkPiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
// close 메서드나 cleaner가 호출한다.
|
||||||
|
@Override public void run() {
|
||||||
|
System.out.println("Cleaning room");
|
||||||
|
numJunkPiles = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 방의 상태. cleanable과 공유한다.
|
||||||
|
private final State state;
|
||||||
|
|
||||||
|
// cleanable 객체. 수거 대상이 되면 방을 청소한다.
|
||||||
|
private final Cleaner.Cleanable cleanable;
|
||||||
|
|
||||||
|
public Room(int numJunkPiles) {
|
||||||
|
state = new State(numJunkPiles);
|
||||||
|
cleanable = cleaner.register(this, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void close() {
|
||||||
|
cleanable.clean();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.cleaner_as_a_safeynet;
|
||||||
|
|
||||||
|
// cleaner 안전망을 갖춘 자원을 제대로 활용하지 못하는 클라이언트 (45쪽)
|
||||||
|
public class Teenager {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new Room(99);
|
||||||
|
System.out.println("Peace out");
|
||||||
|
|
||||||
|
// 다음 줄의 주석을 해제한 후 동작을 다시 확인해보자.
|
||||||
|
// 단, 가비지 컬렉러를 강제로 호출하는 이런 방식에 의존해서는 절대 안 된다!
|
||||||
|
System.gc();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.finalizer;
|
||||||
|
|
||||||
|
import java.lang.ref.ReferenceQueue;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 코드 참고 https://www.baeldung.com/java-finalize
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws InterruptedException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
||||||
|
int i = 0;
|
||||||
|
while (true) {
|
||||||
|
i++;
|
||||||
|
new FinalizerIsBad();
|
||||||
|
|
||||||
|
if ((i % 1_000_000) == 0) {
|
||||||
|
Class<?> finalizerClass = Class.forName("java.lang.ref.Finalizer");
|
||||||
|
Field queueStaticField = finalizerClass.getDeclaredField("queue");
|
||||||
|
queueStaticField.setAccessible(true);
|
||||||
|
ReferenceQueue<Object> referenceQueue = (ReferenceQueue) queueStaticField.get(null);
|
||||||
|
|
||||||
|
Field queueLengthField = ReferenceQueue.class.getDeclaredField("queueLength");
|
||||||
|
queueLengthField.setAccessible(true);
|
||||||
|
long queueLength = (long) queueLengthField.get(referenceQueue);
|
||||||
|
System.out.format("There are %d references in the queue%n", queueLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package com.example.effectivejava.chapter01.item08.finalizer;
|
||||||
|
|
||||||
|
public class FinalizerIsBad {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
System.out.print("");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user