单例模式的几种写法 ,单例设计模式就是所内存中之只加载一次。如何控制呢?下面给出几种实现
第一种懒汉式 延迟加载
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
* 属于延迟加载 懒汉式
*/
public class Singlon {
private static Singlon instance;
private Singlon(){
}
public static Singlon getInstance(){
if(instance==null){
instance=new Singlon();
}
return instance;
}
public static void main(String [] args){
Singlon a = Singlon.getInstance();
Singlon b = Singlon.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}
结果是hashcode相同 是同一个对象
第一种饿汉式 立即加载
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
*/
public class Singlon1 {
private static Singlon1 instance=new Singlon1();
private Singlon1(){
}
public static Singlon1 getInstance(){
return instance;
}
public static void main(String [] args){
Singlon a = Singlon.getInstance();
Singlon b = Singlon.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}
第三种实现静态内部类
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
*/
public class Singlon2 {
private static class MyInStance{
private static Singlon2 singlon2=new Singlon2();
}
public static Singlon2 getInstance(){
return MyInStance.singlon2;
}
public static void main(String [] args){
Singlon2 a = Singlon2.getInstance();
Singlon2 b = Singlon2.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}
第四种用Static代码块实现
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
*/
public class Singlon3 {
private static Singlon3 instance=null;
private Singlon3(){
}
static {
instance=new Singlon3();
}
public static Singlon3 getInstance(){
return instance;
}
public static void main(String [] args){
Singlon3 a = Singlon3.getInstance();
Singlon3 b = Singlon3.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
}
}
第五种用enum枚举数据类型实现单例模式。
下面就上面代码的某些可能出现的线程安全给出改进方法,DCL处理懒汉模式 延迟加载 最优解决方案
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
* 属于延迟加载 饿汉式
* 采用局部加锁 和双锁处理
*/
public class Singlon {
private volatile static Singlon instance;
private Singlon(){
}
public static Singlon getInstance(){
if(instance!=null){
}else {
synchronized(Singlon.class){
if(instance==null){
instance=new Singlon();
}
}
}
return instance;
}
}
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
*/
public class TestTnread extends Thread{
public void run(){
System.out.println(Singlon.getInstance().hashCode());
}
}
package javaThreadandSinglon;
/**
* Created by Administrator on 2016/11/1.
*/
public class Test {
public static void main(String [] args){
TestTnread t1=new TestTnread();
TestTnread t2=new TestTnread();
TestTnread t3=new TestTnread();
t1.start();
t2.start();
t3.start();
}
}
静态内置类线程安全,但是遇到序列化对象也是存在线程安全的,下面给出解决方案, 饿汉线程安全
package javaThreadandSinglon;
import java.io.Serializable;
/**
* Created by Administrator on 2016/11/1.
*/
public class Singlon4 implements Serializable {
private static final long serial=888L;
private static class Singlon4Handle{
private static final Singlon4 instance=new Singlon4();
}
public static Singlon4 getInstance(){
return Singlon4Handle.instance;
}
}
package javaThreadandSinglon;
import java.io.*;
/**
* Created by Administrator on 2016/11/1.
*/
public class SaveAndRead {
public static void main(String [] args) {
FileOutputStream fosref=null;
ObjectOutputStream oosref=null;
FileInputStream fieref=null;
ObjectInputStream iosref=null;
try {
Singlon4 instancs = Singlon4.getInstance();
fosref = new FileOutputStream(new File("myinstance.txt"));
oosref = new ObjectOutputStream(fosref);
oosref.writeObject(instancs);
System.out.println(instancs.hashCode());
fieref=new FileInputStream(new File("myinstance.txt"));
iosref=new ObjectInputStream(fieref);
Singlon4 instace1 = (Singlon4) iosref.readObject();
System.out.println(instace1.hashCode());
}catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if(iosref!=null){
try {
iosref.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fosref!=null){
try {
fosref.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fieref!=null){
try {
fieref.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(oosref!=null){
try {
oosref.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
结果展示
解决方案
加入一段代码
package javaThreadandSinglon;
import java.io.ObjectStreamException;
import java.io.Serializable;
/**
* Created by Administrator on 2016/11/1.
*/
public class Singlon4 implements Serializable {
private static final long serial=888L;
private static class Singlon4Handle{
private static final Singlon4 instance=new Singlon4();
}
public static Singlon4 getInstance(){
return Singlon4Handle.instance;
}
protected Object readResolve()throws ObjectStreamException{
System.out.println("该方法调用");
return Singlon4Handle.instance;
}
}
然后测试代码不变结果是