Java单例模式、多例模式

    //单例设计模式有两种形式:饿汉式/懒汉式
    class Singleton{
    // private volatile static Singleton singleton = null; //懒汉式
     private static final Singleton singleton = new Singleton(); //饿汉式
     private static int count = 0;
     private Singleton(){
     }
     public static Singleton getInstrance(){
    /* 懒汉式
     if(singleton == null){ 
     synchronized(Singleton.class){ 
     if(singleton == null){
     Singleton temp = new Singleton();
     singleton = temp;
     }
     }
     }
    */
     count++;
     return singleton;
     }
     public void print(){
     System.out.println("This is Singleton ,No."+count);
     }
    }
    public class MainEntrance{
     public static void main(String args[]){
     Singleton singleton = Singleton.getInstrance();
     singleton.print();
     Singleton singleton2 = Singleton.getInstrance();
     singleton2.print();
     }
    }
    /* output

This is Singleton ,No.1

This is Singleton ,No.2

*/

程序特点: 构造函数私有化,在类的内部定义static属性与方法,

利用static关键字的特点,不管外部产生多少个Singlton,但是本质上永远只有唯一的一个实例化对象;饿汉式由于它是程序启动时就已实例化,所以在现实一般都不大采用,而更多的采用懒汉式。

下面提供另外一种简单的单例实现,即使用Java的静态内部类。

class SingletonClass{
 private static class SingletonClassInstance{
 private static final SingletonClass instance = new SingletonClass();
 }
 public static SingletonClass getInstance(){
 return SingletonClassInstance.instance;
 }
 private SingletonClass(){
 System.out.println("实例化SingletonClass");
 }
}
public class MainEntrance{ 
 public static void main(String args[]){
 Thread thread = new Thread(new Runnable() {
 public void run() {
 SingletonClass.getInstance();
 }
 });
 Thread thread2 = new Thread(new Runnable() {
 public void run() {
 SingletonClass.getInstance();
 }
 });
 thread.start();
 thread2.start();
 }
}
//output

//实例化SingletonClass

在这段代码中,因为SingletonClass没有static的属性,因此并不会被初始化。直到调用getInstance()的时候,会首先加载SingletonClassInstance类,这个类有一个static的SingletonClass实例,因此需要调用SingletonClass的构造方法,然后getInstance()将把这个内部类的instance返回给使用者。由于这个instance是static的,因此并不会构造多次。

由于SingletonClassInstance是私有静态内部类,所以不会被其他类知道,同样,static语义也要求不会有多个实例存在。并且,JSL规范定义,类的构造必须是原子性的,非并发的,因此不需要加同步块。同样,由于这个构造是并发的,所以getInstance()也并不需要加同步。所以这种方式是比较推荐的。

//多例模式
class Sex{
 private String title;
 private static Sex manSex = new Sex("Man");
 private static Sex womenSex = new Sex("Women");
 private Sex(String title){
 this.title = title;
 }
 public static Sex getInstance(int choose){
 switch (choose) {
 case Choose.MAN:
 return manSex;
 default:
 return womenSex;
 }
 }
 public String getTitle(){
 return title;
 }
}
interface Choose{
 public int MAN = 1;
 public int WOMEN = 2;
}
public class MainEntrance{
 public static void main(String args[]){
 Sex sex = Sex.getInstance(Choose.MAN);
 System.out.println(sex.getTitle());
 Sex sex2 = Sex.getInstance(Choose.WOMEN);
 System.out.println(sex2.getTitle());
 }
}
/*output

man

women

*/

多例模式的特点跟单例模式不同的是,在类中定义了有限个可实例化的对象个数;目的是提供对此类有多个访问入口,在多线程模式下可提高异步效率。
欢迎工作一到五年的Java工程师朋友们加入Java架构开发:855801563

群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代

猜你喜欢

转载自blog.csdn.net/zhuguanghalo/article/details/83591984