单例主要有两种,一种懒汉,一种饿汉,区别在于懒汉在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);
}
}