注册式单例的另一种写法,容器缓存
package com.lchtest.singleton.register;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class ContainerSingleton {
private static Map<String, Object> ioc = new ConcurrentHashMap<>();
private static Object lock = new byte[0];
private ContainerSingleton() {
}
public static Object getInstance(String className) {
Object instance = null;
synchronized (lock){
if (!ioc.containsKey(className)) { //加断点
try {
instance = Class.forName(className).newInstance();
ioc.put(className, instance);
} catch (Exception e) {
e.printStackTrace();
}
return instance;
} else {
return ioc.get(className);
}
}
}
}
ThreadLocal 线程单例
- ThreadLocal 不能保证其 创建的对象是全局唯一,但是能保证在单个线程中是唯一的,天生的线程安全
package com.gupaoedu.vip.pattern.singleton.threadlocal;
/**
*
* 线程内部线程安全,线程间非线程安全的单例
* ThreadLocal本身也是注册式单例
*/
public class ThreadLocalSingleton {
private static final ThreadLocal<ThreadLocalSingleton> threadLocalInstance =
new ThreadLocal<ThreadLocalSingleton>(){
@Override
protected ThreadLocalSingleton initialValue() {
return new ThreadLocalSingleton();
}
};
public static ThreadLocalSingleton getInstance(){
return threadLocalInstance.get();
}
}
测试:
package com.gupaoedu.vip.pattern.singleton.threadlocal;
public class ThreadLocalSingletonTest {
public static void main(String[] args) {
System.out.println(Thread.currentThread() + ":" + ThreadLocalSingleton.getInstance());
System.out.println(Thread.currentThread() + ":" + ThreadLocalSingleton.getInstance());
System.out.println(Thread.currentThread() + ":" + ThreadLocalSingleton.getInstance());
Thread t1 = new Thread(new ExecutorThread());
Thread t2 = new Thread(new ExecutorThread());
t1.start();
t2.start();
}
}
class ExecutorThread implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread() + ":" + ThreadLocalSingleton.getInstance());
System.out.println(Thread.currentThread() + ":" + ThreadLocalSingleton.getInstance());
}
}
可以看到,同一个线程内,单例都是同一个,不同线程之间,获取到的实例不同