单例模式
介绍
单例模式是常用的设计模式之一。
作用就是确保一个类就这一个实例,并自行实例化且向整个系统提供这个实例。
两种类型:饿汉式(类加载时就进行对象实例化)、懒汉式(第一次引用类时才进行对象实例化)。
饿汉式资源利用效率上稍差,但是速度和反应时间上稍好。饿汉式容易在Java中实现,不易在C++中实现。Java中一般默认是懒汉式,但是饿汉式才更加符合Java语言的特点。
代码
饿汉式
public class Singleton{
// 类加载时直接对象实例化
private static Singleton instance = new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return instance;
}
}
懒汉式
懒汉式单例模式实现的方法有多种,如实例方法加锁(synchronized)、双重检查锁、静态内部类等。这里仅仅提供前两种实现。
// synchronized实现方式
public class Singleton{
private static Singleton instance = null;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
// 双重检查锁
public class Singleton{
// 注意这里需要使用valatile保证变量的可见性和指令的有序性
private static volatile Singleton instance = null;
private Singleton(){
}
public static Singleton getInstance(){
if (instance == null){
synchronized(Singleton.class){
if (instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
DEMO
单例类(懒汉式,双重检查锁实现)
public class GlobalNum{
private static volatile GlobalNum gn = null;
private int num = 0;
private GlobalNum(){
}
public static GlobalNum getInsatnce(){
if (gn == null){
synchronized(GlobalNum.class){
if (gn == null){
gn = new GlobalNum();
}
}
}
return gn;
}
private synchronized int getNum(){
return ++num;
}
}
DEMO测试类
启动两个线程分别打印访问次数。
public class Demo{
public static void main(String[] args){
Thread t1 = new MyThread("线程A");
Thread t2 = new MyThread("线程B");
t1.start();
t2.start();
}
}
class MyThread extends Thread{
String name = null;
public MyThread(String name){
this.name = name;
}
@Override
public void run(){
GlobalNum gn = GlobalNum.getInsatnce();
for (int i = 0;i < 5;++i){
System.out.println(name + "第" + gn.getNum() + "次访问!");
try{
this.sleep(1000);
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
}