1、what is 单例模式?
答:设计的一个class只能创建一个实例对象,这样的做法叫做单例模式………………我好粗俗,但是个人理解就这么简单呀
2、实现方式
答:有多种方式,慢慢来吧,常用的………………
a、第一种,简单粗暴型,线程必须安全,因为类加载的时候,就创建好了单例对象,类也只会加载一次,并发下直接卤蛋
public class SingleTest {
private SingleTest() {
super();
System.out.println("SingleTest()");
}
private static SingleTest Instance = new SingleTest();
public static SingleTest getInstance() {
System.out.println("getInstance()");
return Instance;
}
public static void main(String args[]) {
SingleTest sTest = getInstance();
}
}
b、第二种,依然简单粗暴型,线程不安全(和第一种比,实例对象生成时机改变了,第一种类加载时就初始化实例对象,第二种你得调用静态方法时,才生成对象,而且我还作了判断,免得调用一次静态方法,就new一个实例对象,刺激吧)
public class SecSingle {
private static SecSingle instance;
private SecSingle(){
super();
}
public static SecSingle getInstance() {
if (instance == null) {
instance = new SecSingle();
}
return instance;
}
}
c、第三种,线程安全,类加载的时候,就创建类单例对象,换弹没换药
class ThirdSingleton {
private static ThirdSingleton instance;
private ThirdSingleton(){
}
static {
instance = new ThirdSingleton();
}
public static ThirdSingleton getInstance(){
return instance;
}
}
d、第四种,待哥哥来讲,算是a的变体,把静态变量撸成了final的而已,醉了,同样是线程安全
class FourthSingleton {
private final static FourthSingleton mInstance = new FourthSingleton();
private FourthSingleton(){
}
public static FourthSingleton getInstance() {
return mInstance;
}
}
e、第五种,线程安全的(不推荐使用),为静态方法加了一个同步锁(Class类对象锁),每个线程访问该静态方法时,都要等待上一个线程释放类锁,效率比较低
class FifthSingleton {
private static FifthSingleton mInstance;
private FifthSingleton(){
super();
}
public static synchronized FifthSingleton getInstance(){
if(mInstance == null){
mInstance = new FifthSingleton();
}
return mInstance;
}
}
f、第六种,线程安全的(基本不能用),这次加个同步代码块,为啥不推荐使用,缺陷就在于如果有几个线程同时通过了if(mInstance == null),那就要醉了,每个线程都会生成当前class的实例对象了,效率bug
class SixthSingleton {
private static SixthSingleton mInstance;
private SixthSingleton(){
super();
}
public static SixthSingleton getInstance(){
if(mInstance == null) {
synchronized (SixthSingleton.class) {
mInstance = new SixthSingleton();
}
}
return mInstance;
}
}
g、第七种、线程安全(推荐使用,效率相对高),传说中的双重检查null,醉了,弥补了第六种单例模式中的漏洞,爽,就算是3个线程进入if(mInstance == null),里面我又做了一次判断,也就是保证只会生成一个当前class的实例对象了。爽爽
class SeventhSingleton {
private static SeventhSingleton mInstance;
private SeventhSingleton(){
}
public static SeventhSingleton getInstance(){
if(mInstance == null) {
synchronized (SeventhSingleton.class) {
if(mInstance == null) {
mInstance = new SeventhSingleton();
}
}
}
return mInstance;
}
}
h、第八种,利用静态内部类(我还没用过呢),推荐用,利用类加载本身就是线程的
class EighthSingleton {
private EighthSingleton(){
super();
}
private static class Single {
private static final EighthSingleton INSTACE = new EighthSingleton();
}
public static EighthSingleton getInstance(){
return Single.INSTACE;
}
}