diff --git a/src/main/java/top/fjy8018/designpattern/pattern/creational/singleton/ThreadLocalInstance.java b/src/main/java/top/fjy8018/designpattern/pattern/creational/singleton/ThreadLocalInstance.java new file mode 100644 index 0000000..df45d21 --- /dev/null +++ b/src/main/java/top/fjy8018/designpattern/pattern/creational/singleton/ThreadLocalInstance.java @@ -0,0 +1,28 @@ +package top.fjy8018.designpattern.pattern.creational.singleton; + +/** + * 基于{@link ThreadLocalInstance} 的(伪)单例模式,只能保证线程内单例唯一(空间换时间思想) + * + * @author F嘉阳 + * @date 2018-09-25 16:24 + */ +public class ThreadLocalInstance { + private static ThreadLocal instanceThreadLocal = new ThreadLocal() { + @Override + protected ThreadLocalInstance initialValue() { + return new ThreadLocalInstance(); + } + }; + + private ThreadLocalInstance() { + } + + /** + * 其基于{@link java.lang.ThreadLocal.ThreadLocalMap}实现,维护线程隔离,故不用指定key + * + * @return + */ + public static ThreadLocalInstance getInstance() { + return instanceThreadLocal.get(); + } +} diff --git a/src/test/java/top/fjy8018/designpattern/pattern/creational/singleton/ThreadLocalInstanceTest.java b/src/test/java/top/fjy8018/designpattern/pattern/creational/singleton/ThreadLocalInstanceTest.java new file mode 100644 index 0000000..da6db81 --- /dev/null +++ b/src/test/java/top/fjy8018/designpattern/pattern/creational/singleton/ThreadLocalInstanceTest.java @@ -0,0 +1,46 @@ +package top.fjy8018.designpattern.pattern.creational.singleton; + +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +@Slf4j +class ThreadLocalInstanceTest { + + /** + * {@link ThreadLocal} 只能保证在同一个线程中单例安全 + * + * @throws InterruptedException + */ + @Test + void getInstance() throws InterruptedException { + // 在主线程中取 + for (int i = 0; i < 5; i++) { + ThreadLocalInstance instance = ThreadLocalInstance.getInstance(); + log.info(Thread.currentThread().getName() + " " + instance); + } + + Thread thread1 = new Thread(new ThreadLocalInstanceTest.MyRunnable()); + Thread thread2 = new Thread(new ThreadLocalInstanceTest.MyRunnable()); + + thread1.start(); + thread2.start(); + + Thread.sleep(2000); + log.debug("finish"); + } + + private class MyRunnable implements Runnable { + @Override + public void run() { + ThreadLocalInstance instance = null; + try { + instance = ThreadLocalInstance.getInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + log.info(Thread.currentThread().getName() + " " + instance); + } + } +} \ No newline at end of file