单例设计模式

单例设计模式

​ 它是解决某类问题的一套有效的方案(模版)。

一、单例代码书写步骤:

1、私有本类所有的构造方法;

2、创建本类的对象;

3、对外提供一个静态的方法来获取对象。

二、单例常用的两种书写格式:

1、饿汉式:
class Single{
   //  私有所有构造方法
   private Single() {}
   //  在类中创建自己的对象
   private static Single instance = new Single();
   //  对外提供get方法,获取类中唯一的对象
   public static Single getInstance() {
        return instance;
   }
}
2、懒汉式:(常面)
class Single{
    // 私有构造方法
    private Single(){}
    // 只定义变量,不创建对象
    private static Single instance = null;
    // 对外提供方法,获取本类对象
    public static Single getInstance() {
       // 不要直接返回,先判断instance中有没有对象
       if( instance == null ) {
          // 判断成立,说明还没有唯一的对象,则创建对象
          instance = new Single();
        }
          // 有则直接返回该对象
        return instance;
     }
 }

三、常面问题:

1、单例解决的问题是什么?

​ 保证当前的对象在程序中只有一个(对象唯一)。

2、单例模式方法上为什么要加静态?

​ 添加静态的目的是保证外界可以通过类名调用该方法,从而拿到本类的唯一的那个对象。

​ 因为这个类以外的地方没有办法创建类的对象,如果 getInstance 方法不是静态的,导致类以外的别的程序根本就无法获取到这个类的对象了,只有将 getInstance 方法静态了,外界才能通过唯一的这个方法来得到这个类的唯一的那个对象。

3、懒汉式在多线程操作的时候有没有安全问题?

​ 有,在 getInstance 方法中的判断和赋值两行代码上操作共享的 instance 变量,这样在操作的过程中CPU会随机切换,可能出现安全问题。

​ 解决方案:在判断和赋值代码上添加同步代码块。

4、添加同步时效率会降低,能不能优化?

​ 可以。如下所示:

class Single{
	private Single() {}
	private static Single instance = null; 
	/* a.可以定义一个对象作为同步的锁对象—-> synchronized(lock)
     *	 private static Object lock = new Object();
	 * b.因为是静态同步的方法,所以还可以使用格式:synchronized(Single.class)
	 *
	 * 1、此处添加静态的目的是保证外界可以通过类名调用方法名,从而拿到本类的唯一的那个对象	
	 * 2、同步(synchronized)不能添加在此处方法上,会影响后续线程获取唯一对象的效率
	 */
	public static Single getInstance()  {
		/* 3、外面的判断目的是为了后续其他线程在获取对象时提供效率
		 *  当后续其他线程再调用getInstance方法时,由于instance变量中已经有对象了,
		 *  则判断不成立,线程就不用再进入到同步中,更不会判断同步的锁了,从而效率提高
		 */
		if(instance == null) {
			// 4、此处判断和赋值有安全问题,所以添加同步,保证多个线程只有一个线程能够创建对象
			synchronized ( Single.class ) {
				if(instance == null) {
					instance = new Single();
				}
			}
		}
		return instance;
	}
}
//书写线程的任务类
class Demo implements Runnable{
	public void run() {
		System.out.println(Single.getInstance());
	}
}
//书写一个测试类
public class SingleTest {
	public static void main(String[] args) {
        
        //new一个实例对象
		Demo t = new Demo();
        
		//创建线程并启动
		new Thread(t).start();;
		new Thread(t).start();;
	}
}

5、能不能将 synchronized 添加到 run 方法上,为什么?

按照语法规则,是可以在run方法上书写同步的

​ 但是在实际开发中是不可能在run方法上添加同步的。同步方法在线程执行的时候,每个线程要进入这个方法都需要获取同步锁,如果获取不到锁,线程就无法去执行这方法。而run方法是线程要执行的任务方法,如果线程都进不去run方法,相当于线程根本就没有拿到自己的任务。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值