一、单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点[DP].
class Singleton{
private static Singleton instance;
private Singleton() {
}
public static Singleton GetInstance() {//此方法是唯一获得本类实例的唯一全局访问点
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton s1=Singleton.GetInstance();
Singleton s2=Singleton.GetInstance();
if(s1==s2) {
System.out.println("两个对象是相同的实例");
}
}
}
二、多线程时的单例
1、懒汉式,线程安全
加锁synchronized保证单程,在第一次调用时初始化,不浪费内存,但是效率太低。
class Singleton{
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton GetInstance() {
if(instance==null) {
instance =new Singleton();
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton s1=Singleton.GetInstance();
Singleton s2=Singleton.GetInstance();
if(s1==s2) {
System.out.println("两个对象是相同的实例");
}
}
}
2、饿汉式
类加载时就会初始化,没有加锁,执行效率更高,但会浪费内存。
class Singleton {
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton GetInstance() {
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例");
}
}
}
3、双重锁定(DCL)
class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton GetInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例");
}
}
}
4、静态内部类
可以对静态域使用延迟初始化。
class Singleton {
private static class SingletonHolder {
private static final Singleton instance = new Singleton();
}
private Singleton() {
}
public static final Singleton GetInstance() {
return SingletonHolder.instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例");
}
}
}
三、举例:配置文件为例
import java.io.InputStream;
import java.util.Properties;
class AppConfig {
private String parameterA;
private String parameterB;
public String getParameterA() {
return parameterA;
}
public String getParameterB() {
return parameterB;
}
public AppConfig() {
readConfig();
}
private void readConfig() {
Properties p = new Properties();
InputStream in = null;
try {
in = AppConfig.class.getResourceAsStream("AppConfig.properties");
p.load(in);
this.parameterA = p.getProperty("paramA");
this.parameterB = p.getProperty("paramB");
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("装载配置文件出错");
e.printStackTrace();
} finally {
try {
in.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
AppConfig config = new AppConfig();
String paramA = config.getParameterA();
String paramB = config.getParameterB();
System.out.println("paramA=" + paramA + ",paramB=" + paramB);
}
}
用单例模式改写:
class AppConfig {
private static AppConfig instance;
public AppConfig() {
}
public static AppConfig GetInstance() {
if (instance == null) {
instance = new AppConfig();
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
AppConfig paramA = new AppConfig();
AppConfig paramB = new AppConfig();
System.out.println("paramA=" + paramA + ",paramB=" + paramB);
}
}