package dev.elaine.concurrency;

import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public final class ThreadLocalLeakSample {
    private static final ThreadLocal<String> REQUEST_ID = new ThreadLocal<>();

    private ThreadLocalLeakSample() {
    }

    public static String reproduceLeak() throws Exception {
        try (var executor = Executors.newSingleThreadExecutor()) {
            executor.submit(() -> REQUEST_ID.set("request-A")).get();
            Future<String> nextRequest = executor.submit(REQUEST_ID::get);
            return nextRequest.get();
        }
    }

    public static String runWithCleanup() throws Exception {
        try (var executor = Executors.newSingleThreadExecutor()) {
            executor.submit(() -> {
                try {
                    REQUEST_ID.set("request-A");
                } finally {
                    REQUEST_ID.remove();
                }
            }).get();
            return executor.submit(REQUEST_ID::get).get();
        }
    }

    public static void main(String[] args) throws Exception {
        System.out.println("未清理时下一请求读到=" + reproduceLeak());
        System.out.println("清理后下一请求读到=" + runWithCleanup());
    }
}
