Java 单例设计模式

单例模式,顾名思义就是确保一个类只有一个实例。单例模式英文原话“Ensure a class has only one instance,and provide a global point of access to it.”翻译,单例模式是确保一个类只有一个实例,而且自行实例化并向这个系统提供这个实例。单例模式通常分三种:饿汉式单例类、懒汉式单例类和登记式单例类。下面说说前两种单例类。

饿汉式单例类是在类加载时,进行对象实例化;懒汉式单例类是在第一次引用该类时进行对象实例化。

饿汉式单例类代码如下所示:

public class Singleton{
	private static Singleton _instance = new Singleton();
	//构造方法私有,保证外界不能直接实例化;
	private Singleton(){
		
	}
	
	//通过该方法获得实例对象;
	public static getInstance(){
		return _instance;
	}
}

懒汉式单例类代码如下所示:

public class Singleton{
	private static Singleton _instance =null;
	//构造方法私有,保证外界不能直接实例化;
	private Singleton(){
		
	}
	
	//通过该方法获得实例对象,此时应该同步,防止多个线程同时调用该方法而创建多个实例;
	public static synchronized getInstance(){
		if(_instance==null){
			_instance = new Singleton();
		}
		return _instance
	}
}
以上代码片段可以看出饿汉式单例类和懒汉式单例类的差别。需要注意的是,懒汉式单例获得实例的方法需要同步,饿汉式不必同步,因为实例在类加载时已经创建了,即使多个线程同时调用该方法获得还是同个实例;单例类的构造方法都是私有的。下面写一个多线程访问单列类的demo,demo中使用的是饿汉式单例类,其实Java语言更适合使用饿汉式单例类。下面上代码。

单例类如下:

//单例类,该单例类实现一个计数功能;
public class NumController {
	private static NumController nController = new NumController();
	private int num = 0;
	
	//单例类的构造函数是private的,只供自己调用;
	private NumController(){
		
	}
	
	//向调用者提供单例对象;
	public static  NumController getInstance(){
		return nController;
	}
	
	//计数器加1,注意要同步;
	public synchronized int getNum(){
		return num++;
	}
}

下面是主函数类:

public class SingletonPatternTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//创建两个访问单例类的线程,由于线程是用内部类实现,所以需要先创建一个外围对象;
		SingletonPatternTest spt = new SingletonPatternTest();
		//将单例类对象传递给线程;
		Thread threadOne = spt.new ThreadOne(NumController.getInstance());
		Thread threadTwo = spt.new ThreadTwo(NumController.getInstance());
		//开启线程
		threadOne.start();
		threadTwo.start();
	}
	
	class ThreadOne extends Thread{
		NumController nController;
		public ThreadOne(){
			
		}
		
		public ThreadOne(NumController nController){
			this.nController=nController;
		}
		
		public void run(){
			for(int i=0;i<5;i++){
				System.out.println("这是ThreadOne第"+nController.getNum()+"次访问NumController");
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	class ThreadTwo extends Thread{
		NumController nController;
		public ThreadTwo(){
			
		}
		public ThreadTwo(NumController nController){
			this.nController=nController;
		}
		
		public void run(){
			for(int i=0;i<5;i++){
				System.out.println("这是ThreadTwo第"+nController.getNum()+"次访问NumController");
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
}

运行结果如下:

这是ThreadOne第0次访问NumController
这是ThreadTwo第1次访问NumController
这是ThreadTwo第2次访问NumController
这是ThreadOne第3次访问NumController
这是ThreadOne第4次访问NumController
这是ThreadTwo第5次访问NumController
这是ThreadOne第6次访问NumController
这是ThreadTwo第7次访问NumController
这是ThreadOne第8次访问NumController
这是ThreadTwo第9次访问NumController




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值