//单例设计模式有两种形式:饿汉式/懒汉式
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等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代