简单java单例模式 懒汉式、饿汉式以及解决线程安全问题(synchronized)

单例模式(又称设计模式)

一个类只存一个对象(实例)。

单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数额控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。


单例模式中有懒汉式和饿汉式两种

下面说一下懒汉式和饿汉式的区别及优点:

饿汉式不管有没有调用getInstance()方法,都会预先在系统中创建一个静态对象
懒汉式不会预先创建对象,只有在第一次调用时才创建对象
饿汉式优点: 在多线程模式下是安全的
缺点: 没有调用方法前就被加载,会占用内存
懒汉式优点:只有调用方法才创建对象,不会占用内存
缺点:在多线程模式下不安全
举例说明:

一个系统共享一个对象:Person类

public class Person {

	private int id;	
	public Person(int id){
		this.id = id;
	}
	public Person() {
		super();
	}
	
	public void test(){
		Singleton sing = Singleton.getInstance();
		System.out.println(sing.hashCode());
	}
}
单例模式中的懒汉式:

public class Singleton {

	//私有化构造
	private Singleton(){
		System.out.println("对象创建成功");
	}
	
	//全局对象
	private static Singleton singleton = null;	
	
	//调用getInstance方法才会创建对象
	public static synchronized Singleton getInstance(){
		//判断全局对象是否为空
		if(singleton == null){
			//如果为空,就创建该对象
			singleton = new Singleton();
		}
		//如果不为空,返回该对象
		return singleton;
	}
	
	public static void main(String[] args) {		
		//多线程操作
		//2.直接使用Thread操作
		Thread thread1 = new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//
				Singleton sin = Singleton.getInstance();
				System.out.println(sin.hashCode());
			}
		};
		//开启新线程
		thread1.start();
		
		Thread thread2 = new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Singleton sin2 = Singleton.getInstance();
				System.out.println(sin2.hashCode());
			}
		};		
		
		thread2.start();
			
		Person person  = new Person();
		person.test();
		
		Singleton sin3 = new Singleton();
		System.out.println(sin3.hashCode());//与上不同
单例模式中的饿汉式:
public class Singleton2 {

	//跟懒汉式的区别:直接创建对象
	private static Singleton2 ton = new Singleton2();
	
	//私有构造
	private Singleton2(){
		System.out.println("对象创建成功");
	}
	
	public static Singleton2 getInstance(){
		return ton;		
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Singleton2 ton = Singleton2.getInstance();
		System.out.println(ton.hashCode());
	}
}
单例模式中的线程安全问题以及解决方案


懒汉式解决线程安全问题

public class Singleton3 {
	private Singleton3() {
		System.out.println("对象创建成功");
	}
	
	//全局对象
	private static Singleton3 singleton=null;
	
	public static Singleton3 getInstance() {
		//判断全局对象是否为空
		if(singleton==null) {
			//休眠一秒钟
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//线程锁
			synchronized (Singleton3.class) {
				if(singleton==null) {
					//如果为空,就创建该类对象
					singleton=new Singleton3();
				}
			}
		}
		//如果不为空,就直接返回该对象
		return singleton;
	}
	
	public static void main(String[] args) {
		//多线程操作
		//2.直接使用Thread操作
		Thread thread1=new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//
				Singleton3 ton=Singleton3.getInstance();
				System.out.println(ton.hashCode());
			}
		};
		thread1.start();
		Thread thread2=new Thread(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Singleton3 ton2=Singleton3.getInstance();
				System.out.println(ton2.hashCode());
			}
		};
		//开启新线程
		thread2.start();
	}
}

深入了解java单例模式:http://devbean.blog.51cto.com/448512/203501/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值