设计模式 之 单例模式

时间:2022-12-11 08:01:51

单例主要有两种,一种懒汉,一种饿汉,区别在于懒汉在getInstance的时候,才会去初始化单例,而饿汉在类加载之后就立即进行初始化。可见懒汉节省资源,而饿汉的在于天生的线程安全

1.懒汉式单例

package com.test.pattern;

class Singleton {
private static Singleton singleton;
private Singleton(){
System.out.println(
"hello I'm singleton "+this.hashCode());
}
public static Singleton getSingleton() {
if(singleton == null)
singleton
= new Singleton();
return singleton;
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton.getSingleton();
Singleton.getSingleton();
Singleton.getSingleton();
}
}

这种单例模式是线程不安全的(但如果将getSingleton方法声明为synchronized即可使之线程安全):

package com.test.pattern;

/**
*
@author wangx
* @Date: 2016年8月8日
* @func: 懒汉式单例多线程不安全
* @Copyright: 2016 wangx. All rights reserved.
*/
public class SingletonMultithread {
public static void main(String[] args) {
new Thread(new Task()).start();
new Thread(new Task()).start();
}
}

class Task implements Runnable {

@Override
public void run() {
Singleton.getSingleton();
Singleton.getSingleton();
}
}

运行结果:

hello I'm singleton 1025866005
hello I'm singleton 1449742585

 

2.饿汉式单例

package com.test.pattern;

/**
*
@author wangx
* @Date: 2016年8月9日
* @func: 饿汉式单例
* @Copyright: 2016 wangx. All rights reserved.
*/
class Singleton2 {
private static Singleton2 singleton=new Singleton2();
private Singleton2() {
System.out.println(
"I'm singleton "+this.hashCode());
}
public static Singleton2 getInstance() {
return singleton;
}
}
public class SingletonTest2 {
public static void main(String[] args) {
new Thread(new Task2()).start();
new Thread(new Task2()).start();
}
}

class Task2 implements Runnable{
@Override
public void run() {
Singleton2.getInstance();
}
}

 

终:通过反射机制破坏单例

package com.test.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class HelloWorld {
public void sayHello() {
System.out.println(
"hello world");
}
}
class Singleton {
private Singleton(){}
private static Singleton singleton;
public Singleton getSingleton() {
if(singleton == null)
singleton
= new Singleton();
return singleton;
}
public void sayHello() {
System.out.println(
"hello I'm singleton "+this.hashCode());
}
}
public class ReflectionTest {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
Constructor constructor
= Class.forName("com.test.reflection.Singleton").getDeclaredConstructor();
constructor.setAccessible(
true);
Method sayHello
= Class.forName("com.test.reflection.Singleton").getDeclaredMethod("sayHello", null);
sayHello.invoke(constructor.newInstance(),
null);
sayHello.invoke(constructor.newInstance(),
null);
}
}