ThreadLocal实现伪单例并测试线程安全性

This commit is contained in:
2018-09-25 16:33:47 +08:00
parent 0e5bad0fc4
commit 644292961b
2 changed files with 74 additions and 0 deletions

View File

@@ -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<ThreadLocalInstance> instanceThreadLocal = new ThreadLocal<ThreadLocalInstance>() {
@Override
protected ThreadLocalInstance initialValue() {
return new ThreadLocalInstance();
}
};
private ThreadLocalInstance() {
}
/**
* 其基于{@link java.lang.ThreadLocal.ThreadLocalMap}实现维护线程隔离故不用指定key
*
* @return
*/
public static ThreadLocalInstance getInstance() {
return instanceThreadLocal.get();
}
}

View File

@@ -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);
}
}
}