JAVA设计模式---单例模式(singleton)

1.首先看一个Java的简单版本的log类

public class LogUtil {

	private static LogUtil sLogUtil;

	public final int DEGUB = 0;

	public final int INFO = 1;

	public final int ERROR = 2;

	public final int NOTHING = 3;

	public int level = DEGUB;

	private LogUtil() {
	}

	public static LogUtil getInstance() {
		if (sLogUtil == null) {
			sLogUtil = new LogUtil();
		}
		return sLogUtil;
	}

	public void debug(String msg) {
		if (DEGUB >= level) {
			System.out.println(msg);
		}
	}

	public void info(String msg) {
		if (INFO >= level) {
			System.out.println(msg);
		}
	}

	public void error(String msg) {
		if (ERROR >= level) {
			System.out.println(msg);
		}
	}

}
首先将LogUtil的构造函数私有化,这样就无法使用new关键字来创建LogUtil的实例了。然后使用一个sLogUtil私有静态变量来保存实例,并提供一个公有的getInstance方法用于获取LogUtil的实例,在这个方法里面判断如果 sLogUtil为空,就new出一个新的LogUtil实例,否则就直接返回sLogUtil。这样就可以保证内存当中只会存在一个LogUtil的实例了。单例模式完工!这时打印日志的代码需要改成如下方式:
LogUtil.getInstance().debug("Hello World");


2.对于上面的代码在多线程的时候可能会出现问题。

	public static LogUtil getInstance() {
		if (sLogUtil == null) {
			sLogUtil = new LogUtil();
		}
		return sLogUtil;
	}

如果现在有两个线程同时在执行getInstance方法,第一个线程刚执行完第2行,还没执行第3行,这个时候第二个线程执行到了第2行,它会发现sLogUtil还是null,于是进入到了if判断里面。这样你的单例模式就失败了,因为创建了两个不同的实例。

方案一:

public synchronized static LogUtil getInstance() {
		if (sLogUtil == null) {
			sLogUtil = new LogUtil();
		}
		return sLogUtil;
	}
方案二:

public static LogUtil getInstance() {
		synchronized (LogUtil.class) {
			if (sLogUtil == null) {
				sLogUtil = new LogUtil();
			}
			return sLogUtil;
		}
	}
方案三:

public static LogUtil getInstance() {
		if (sLogUtil == null) {
			synchronized (LogUtil.class) {
				if (sLogUtil == null) {
					sLogUtil = new LogUtil();
				}
			}
		}
		return sLogUtil;
	}

方案一与方案二都解决了是否是单例(singleton)的问题,但是每次调用getInstance(),都会被同步锁同步,降低了效率。

方案三应该是最佳的方案。


3.下面是我自己写的一个android中用到的LOG类

package Util;

import android.util.Log;

/**
 * Created by lq on 16-8-25.
 *
 */
public class LogUtil {
    private static LogUtil mLogUtil;

    private final int DEBUG = 0;
    private final int INFO = 1;
    private final int ERROR = 2;
    private final int NOTHING = 3;

    private  int mLevel = DEBUG;

    private LogUtil(){

    }

    public LogUtil getInstance(){
        if(mLogUtil == null){
            synchronized (LogUtil.class){
                if(mLogUtil == null)  mLogUtil = new LogUtil();
            }
        }
        return mLogUtil;
    }

    public void setLevel(int level){
        if(level < 4 && level > -1)
            mLevel = level;
    }
    
    public void d(String tag, String msg){
        if(DEBUG >= mLevel){
            Log.d(tag,msg);
        }
    }

    public void i(String tag, String msg){
        if(INFO >= mLevel){
            Log.i(tag,msg);
        }
    }

    public void e(String tag, String msg){
        if(ERROR >= mLevel){
            Log.e(tag,msg);
        }
    }
}

singleton优秀博客:

http://blog.csdn.net/guolin_blog/article/details/8860649



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值