Java单例设计模式
一个类有且只有一个实例,保证在内存中只存在一个实例化的对象,避免对同一资源的多重占用。
作用:创建一个类对象时,保证全局对外只提供一个实例对象,提供一种访问该类的唯一对象方式,直接访问不需要进行实例化。能够避免全局使用类被频繁创建销毁时的资源浪费。
缺点:无接口,不能被继承。(static
修饰所致)
单例设计模式要素:
- 一个私有的构造器
- 一个私有的该类类型的变量
- 必须有一个共有的返回类型为该类类型的方法,用来返回这个唯一的变量
常用的四种单例设计模式(多使用饿汉式。)
(使用person类
进行包含一个属性name,演示所用,不使用私有属性及get与set方法。)
public class Person {
private static Person person = new Person();
public String name;
private Person(){}
/**
* 使用共有的getInstance()返回该类的实例化对象
*/
public static Person getInstance() {
return person;
}
}
- 非线程安全
public class Person {
private static Person person;
public String name;
private Person(){}
public static Person getPerson() {
if(person == null){
person = new Person();
}
return person;
}
}
- 线程安全(synchronized同步方法)
缺点:synchronized同步方法会带来极大的cpu开销,效率较低
public class Person {
private static Person person;
public String name;
private Person(){}
public static synchronized Person getPerson() {
if(person == null){
person = new Person();
}
return person;
}
}
public class Person {
// 关键字volatile 防止指令重排,保证返回对象在创建对象后。
private volatile static Person person;
public volatile String name;
private Person(){}
public static Person getPerson() {
//检查是否有引用指向对象,高并发下可能会有多个线程同时进入,
if(person == null){
//synchronized保证只有一个线程进入。主要过滤多线程。
synchronized (Person.class){
//第一层检查后,当线程A创建了一个对象后,如果只有一层检查,那么线程B可能又再次创建一个对象,导致两次两个对象不一样。
if(person == null){
person = new Person();
}
}
}
return person;
}
}
public class Person {
public String name;
private static class Man{
private static final Person person = new Person();
}
private Person(){}
public static final Person getInstance(){
return Man.person;
}
}
注:有问题请及时评论区反馈,小白作者,简单总结,惭愧惭愧。