#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