zoukankan      html  css  js  c++  java
  • 设计模式 之 单例模式

    单例主要有两种,一种懒汉,一种饿汉,区别在于懒汉在getInstance的时候,才会去初始化单例,而饿汉在类加载之后就立即进行初始化。可见懒汉节省资源,而饿汉的在于天生的线程安全

    1.懒汉式单例

    package com.test.pattern;
    
    class Singleton {
        private static Singleton singleton;
        private Singleton(){
            System.out.println("hello I'm singleton "+this.hashCode());
        }
        public static Singleton getSingleton() {
            if(singleton == null)
                singleton = new Singleton();
            return singleton;
        }
    }
    public class SingletonTest {
        public static void main(String[] args) {
            Singleton.getSingleton();
            Singleton.getSingleton();
            Singleton.getSingleton();
        }
    }

    这种单例模式是线程不安全的(但如果将getSingleton方法声明为synchronized即可使之线程安全):

    package com.test.pattern;
    
    /**
     * @author wangx
     * @Date: 2016年8月8日 
     * @func: 懒汉式单例多线程不安全
     * @Copyright: 2016 wangx. All rights reserved.
     */
    public class SingletonMultithread {
        public static void main(String[] args) {
            new Thread(new Task()).start();
            new Thread(new Task()).start();
        }
    }
    
    class Task implements Runnable {
    
        @Override
        public void run() {
            Singleton.getSingleton();
            Singleton.getSingleton();
        }
    }

    运行结果:

    hello I'm singleton 1025866005
    hello I'm singleton 1449742585

    2.饿汉式单例

    package com.test.pattern;
    
    /**
     * @author wangx
     * @Date: 2016年8月9日 
     * @func: 饿汉式单例
     * @Copyright: 2016 wangx. All rights reserved.
     */
    class Singleton2 {
        private static Singleton2 singleton=new Singleton2();
        private Singleton2() {
            System.out.println("I'm singleton "+this.hashCode());
        }
        public static Singleton2 getInstance() {
            return singleton;
        }
    }
    public class SingletonTest2 {
        public static void main(String[] args) {
            new Thread(new Task2()).start();
            new Thread(new Task2()).start();
        }
    }
    
    class Task2 implements Runnable{
        @Override
        public void run() {
            Singleton2.getInstance();
        }
    }

    终:通过反射机制破坏单例

    package com.test.reflection;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    class HelloWorld {
        public void sayHello() {
            System.out.println("hello world");
        }
    }
    class Singleton {
        private Singleton(){}
        private static Singleton singleton;
        public Singleton getSingleton() {
            if(singleton == null)
                singleton = new Singleton();
            return singleton;
        }
        public void sayHello() {
            System.out.println("hello I'm singleton "+this.hashCode());
        }
    }
    public class ReflectionTest {
        public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
            Constructor constructor = Class.forName("com.test.reflection.Singleton").getDeclaredConstructor();
            constructor.setAccessible(true);
            Method sayHello = Class.forName("com.test.reflection.Singleton").getDeclaredMethod("sayHello", null);
            sayHello.invoke(constructor.newInstance(),null);
            sayHello.invoke(constructor.newInstance(),null);
        }
    }
  • 相关阅读:
    Ubuntu安装vsftp软件
    linux下LNMP环境安装笔记
    thinkphp在app接口开发过程中的通讯安全认证
    thinkphp在app接口开发过程中的通讯数据的封装
    thinkphp微信开发之jssdk拉取卡券及卡券的核销
    thinkphp微信开发之jssdk图片上传并下载到本地服务器
    用thinkphp进行微信开发的整体设计思考
    我常用的自定义函数之rmdir php删除目录及目录下的所有文件
    我常用的自定义函数之p 用于打印数据,调试代码很方便
    我常用的自定义函数之clean php自动过滤功能
  • 原文地址:https://www.cnblogs.com/heben/p/5749051.html
Copyright © 2011-2022 走看看