ThreadLocal实现伪单例并测试线程安全性
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user