您的位置:首页 > 编程语言 > Java开发

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

2016-08-25 10:59 253 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android java