其中单例模式
1、恶汉式单例模式
public class SingleTon {
private static SingleTon instance=new SingleTon();
private Person person;
private byte[] b=new byte[1024];
private SingleTon() {
}
private SingleTon(Person person) {
this.person = person;
}
public static SingleTon getInstance(){
return instance;
}
}
优点: instance实例作为静态变量在类初始化阶段的过程中被收集到方法中,该方法是同步方法,即使在多线程情况下也只会被实例化一次;
缺点:如果instance创建后,很长一段时间才用,这段时间instance实例会一直驻留在堆内存,造成内存浪费;
2、懒汉式单例模式
public class LazySingleTon {
private static LazySingleTon instance;
private Person mPerson;
private LazySingleTon(Person person) {
mPerson = person;
}
private LazySingleTon() {
}
public static LazySingleTon getInstance(){
if (instance==null){
instance=new LazySingleTon();
}
return instance;
}
}
缺点:instance在多线程中可能被实例化多次,无法保证实例的唯一性;比如线程1执行到if判断是,被切换到线程2,这是实例还未创建仍然为null,if()判断仍然满足,就造成线程1,2都创建了实例;
3、懒汉式+同步方式单例模式
public class LazySingleTon {
private static LazySingleTon instance;
private Person mPerson;
private LazySingleTon(Person person) {
mPerson = person;
}
private LazySingleTon() {
}
public static synchronized LazySingleTon getInstance(){
if (instance==null){
instance=new LazySingleTon();
}
return instance;
}
}
缺点:synchronize的排他性,同一时刻只有一个线程可以访问,效率低下;
4、Double-Check
public class LazySingleTon {
private static LazySingleTon instance;
private Person mPerson;
private LazySingleTon(Person person) {
mPerson = person;
}
private LazySingleTon() {
}
public static LazySingleTon getInstance(){
if(instance==null){
synchronized (LazySingleTon.class) {
if (instance == null) {
instance = new LazySingleTon();
}
}
}
return instance;
}
}
缺点:可能抛空指针异常,创建instance实例,也必须实例化Person,根据指令重排序和Happens-Before规则,这两者没有前后关系约束,可能instance已经完成实例化,而Person还未完被实例化,调用Person对象的方法,就会报空指针异常;
Volatile+Double-check
public class LazySingleTon {
private static volatile LazySingleTon instance;
private Person mPerson;
private LazySingleTon() {
this.mPerson..//Perosn初始化
}
public static LazySingleTon getInstance(){
if(instance==null){
synchronized (LazySingleTon.class) {
if (instance == null) {
instance = new LazySingleTon();
}
}
}
return instance;
}
}
通过volatile关键字禁止指令重排序;
优点:满足多线程下实例单一性、懒加载、已经解决了上一种方式可能出现的空指针情况;
5、Holder式单例模式
public class HolderSingleTon {
private HolderSingleTon() {
}
public static HolderSingleTon getInstance(){
return Holder.instance;
}
public static class Holder{
private static HolderSingleTon instance=new HolderSingleTon();
}
}
HolderSingleton类中没有静态instance实例,因此其在初始化时不会创建HolderSingleTon对象;只有Holder被主动引用时,才会创建HolderSingleTon实例,而实例创建过程在java编译期收集至方法中,方法是同步方法,因此可以保证原子性、可见性、有序性;
6、枚举式单例模式
public enum EnmuSingleTon {
INSTANCE;
private byte[] b=new byte[1024];
public static void method(){
//调用该方法会立即导致instance实例化;
}
private static EnmuSingleTon getInstance(){
return INSTANCE;
}
}
优点:线程安全只能被实例化一次
缺点:不能够懒加载,调用其静态方法instance会立即实例化;
改进版:增加懒加载特性
public class EnmuLazySingleTon {
private byte[] b = new byte[1024];
private enum Holder {
HOLDER;
private EnmuLazySingleTon instance;
Holder() {
instance = new EnmuLazySingleTon();
}
private EnmuLazySingleTon getSingleTon() {
return instance;
}
}
public static void method() {
}
public static EnmuLazySingleTon getInstance() {
return Holder.HOLDER.getSingleTon();
}
}