咱們先看代碼吧java
public class ContainerSingleton {
private ContainerSingleton(){
}
private static Map<String,Object> singletonMap = new HashMap<String,Object>();
public static void putInstance(String key,Object instance){
if(StringUtils.isNotBlank(key) && instance != null){
if(!singletonMap.containsKey(key)){
singletonMap.put(key,instance);
}
}
}
public static Object getInstance(String key){
return singletonMap.get(key);
}
}
複製代碼
這種方式實現的單例是線程不安全的。若是須要線程安全的可使用HashTable可是HashTable每次存取都會加上同步鎖,性能損耗比較嚴重。或者使用ConcurrentHashMap。安全
這個單例嚴格意義上講並不徹底算是單例,它只能算在單個線程中的單例,也就是在同一個線程中的它是單例的。咱們直接看代碼吧。bash
public class ThreadLocalInstance {
private static final ThreadLocal<ThreadLocalInstance> threadLocalInstanceThreadLocal
= new ThreadLocal<ThreadLocalInstance>(){
@Override
protected ThreadLocalInstance initialValue() {
return new ThreadLocalInstance();
}
};
private ThreadLocalInstance(){
}
public static ThreadLocalInstance getInstance(){
return threadLocalInstanceThreadLocal.get();
}
}
複製代碼
而後咱們寫個測試類測試一下。ide
咱們定義一個線程T,在這個線程裏面獲取這個單例對象。函數
public class T implements Runnable {
@Override
public void run() {
ThreadLocalInstance instance = ThreadLocalInstance.getInstance();
System.out.println(Thread.currentThread().getName()+" "+instance);
}
}
複製代碼
而後是測試類包含主函數。性能
public class SingletonTest {
public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
System.out.println("main thread"+ThreadLocalInstance.getInstance());
System.out.println("main thread"+ThreadLocalInstance.getInstance());
System.out.println("main thread"+ThreadLocalInstance.getInstance());
System.out.println("main thread"+ThreadLocalInstance.getInstance());
System.out.println("main thread"+ThreadLocalInstance.getInstance());
System.out.println("main thread"+ThreadLocalInstance.getInstance());
Thread t1 = new Thread(new T());
Thread t2 = new Thread(new T());
t1.start();
t2.start();
System.out.println("program end");
}
複製代碼
咱們再看一下運行結果。測試
main threadcom.design.pattern.creational.singleton.ThreadLocalInstance@12edcd21
main threadcom.design.pattern.creational.singleton.ThreadLocalInstance@12edcd21
main threadcom.design.pattern.creational.singleton.ThreadLocalInstance@12edcd21
main threadcom.design.pattern.creational.singleton.ThreadLocalInstance@12edcd21
main threadcom.design.pattern.creational.singleton.ThreadLocalInstance@12edcd21
main threadcom.design.pattern.creational.singleton.ThreadLocalInstance@12edcd21
program end
Thread-0 com.design.pattern.creational.singleton.ThreadLocalInstance@3ec28870
Thread-1 com.design.pattern.creational.singleton.ThreadLocalInstance@7a56389b
複製代碼
從結果咱們能夠看出這個單例之算是個僞單例,只能在一個線程裏面實現單例。spa