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");
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