美文网首页
设计模式:单例模式(4)

设计模式:单例模式(4)

作者: 谁家的猪 | 来源:发表于2019-07-24 08:29 被阅读0次

    容器单例模式

    代码演示

    1. 创建ContainerSingleton类
    import org.apache.commons.lang3.StringUtils;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @author lijiayin
     */
    public class ContainerSingleton {
        private ContainerSingleton() {
            
        }
        private static Map<String, Object> singletonMap = new HashMap<>();
        
        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);
        }
    }
    
    1. 创建测试类
    /**
     * @author lijiayin
     */
    public class ContainerTest {
    
        public static void main(String[] args) {
            Thread t1 = new Thread(() -> {
                ContainerSingleton.putInstance("object", new Object());
                Object instance = ContainerSingleton.getInstance("object");
                System.out.println(Thread.currentThread().getName() + ":" + instance);
            });
            Thread t2 = new Thread(() -> {
                ContainerSingleton.putInstance("object", new Object());
                Object instance = ContainerSingleton.getInstance("object");
                System.out.println(Thread.currentThread().getName() + ":" + instance);
            });
            t1.start();
            t2.start();
            System.out.println("program end");
        }
    }
    
    1. 测试结果


      测试结果.png
    2. 注意
      虽然返回是同一个对象,但是特殊场景存在问题。
      第一个线程放入一个对象,第二个线程也放入一个对象,然后都调用返回方法,返回的都是第二个对象。此时返回的是同一个对象。
      当第一个线程放入一个对象时,调用返回方法,返回第一个对象;然后第二个线程才放入第二个对象,调用返回方法,返回第二个对象。此时返回的是不同的对象。
      使用时要特别注意!

    ThreadLocal线程“单例”

    代码演示

    1. 创建ThreadLocalSingleton类
    /**
     * @author lijiayin
     */
    public class ThreadLocalSingleton {
        private static final ThreadLocal<ThreadLocalSingleton> threadLocalSingleton
                = ThreadLocal.withInitial(ThreadLocalSingleton::new);
        private ThreadLocalSingleton(){
            
        }
        public static ThreadLocalSingleton getInstance(){
            return threadLocalSingleton.get();
        }
    }
    
    1. 创建测试类
    /**
     * @author lijiayin
     */
    public class ThreadLocalTest {
    
        public static void main(String[] args) {
            System.out.println("main:" + ThreadLocalSingleton.getInstance());
            System.out.println("main:" + ThreadLocalSingleton.getInstance());
            System.out.println("main:" + ThreadLocalSingleton.getInstance());
            System.out.println("main:" + ThreadLocalSingleton.getInstance());
            Thread t1 = new Thread(() -> {
                ThreadLocalSingleton instance = ThreadLocalSingleton.getInstance();
                System.out.println(Thread.currentThread().getName() + ":" + instance);
            });
            Thread t2 = new Thread(() -> {
                ThreadLocalSingleton instance = ThreadLocalSingleton.getInstance();
                System.out.println(Thread.currentThread().getName() + ":" + instance);
            });
            t1.start();
            t2.start();
            System.out.println("program end");
        }
    }
    
    1. 测试结果


      测试结果.png
    2. 结论
      这种方式,在单个线程中是同一个对象,对象为线程私有。

    开源框架应用

    1. 饿汉式:Runtime
    2. 容器单例:Desktop.getDesktop()

    相关文章

      网友评论

          本文标题:设计模式:单例模式(4)

          本文链接:https://www.haomeiwen.com/subject/hhbmlctx.html