单例模式
单例模式的特点:
一是某个类只能有一个实例
二是它必须自行创建这个实例
三是它必须自行向整个系统提供这个实例
应用情况:对于多个对象使用同一个配置信息时,就需要保证该对象的唯一性。
如何保证对象的唯一性
一不允许其他程序用new创建该类对象那个。
二在该类创建一个本类实例
三对外提供一个方法让其他程序可以获取该对象
实现的方法:
一是构造函数私有化
二是类定义中含有一个该类的静态私有对象
三是该类提供了一个静态的公共的函数用于创建或获取它本身的静态私有对象
方法一 饿汉式
public class Person1 {
//定义该类的静态私有对象
private static final Person1 person1 =new Person1();
//构造函数私有化
private Person1(){
}
//一个静态的公共的函数用于创建或获取它本身的静态私有对象
public static Person1 getPerson1() {
return person1;
}
}
该方法虽然在多线程下也能正确运行但是不能实现延迟加载(什么是延迟加载?)
资源效率不高,可能getPerson1()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化
public class Person1 {
private static Person1 person1 =null;
private Person1(){
}
public static Person1 getPerson1() {
if(person1==null){
person1=new Person1();
}
return person1;
}
}
该方法只能在单线程下运行,当在多线程下运行时可能会出现创建多个实例的情况。
对该方法可以进行优化
懒汉式 (优化一)
public class Person1 {
private static Person1 person1 =null;
private Person1(){
}
public static synchronized Person1 getPerson1() {
if(person1==null){
person1=new Person1();
}
return person1;
}
}
该方法虽然能保证多线程下正常运行,但是效率很低,因为
person1=new Person1(); 这句话在整个程序运行中只执行一次,但是所有调用getPerson1的线程都要进行同步,这样会大大减慢程序的运行效率。所以虽然该优化解决了问题但是并不好。
懒汉式 (优化二)
public class Person1 {
private static Person1 person1 =null;
private Person1(){
}
public static Person1 getPerson1() {
if(person1==null){
synchronized(Person1.class){
if(person1==null)
person1=new Person1();
}
}
return person1;
}
}
这个优化比较好的解决了多线程问题,而且效率也很好,同时也兼顾了lazy loading。
方法三加锁实现
import java.util.concurrent.locks.ReentrantLock;
public class Person1 {
private static Person1 person1 =null;
private static ReentrantLock lock = new ReentrantLock(false); // 创建可重入锁,false代表非公平锁
private Person1(){
}
public static Person1 getPerson1() {
if(person1==null){
lock.lock();
try{
if(person1==null)
person1=new Person1();
}finally{
lock.unlock();
}
}
return person1;
}
}
该方法和
懒汉式 (优化二)非常类似
方法四 静态内部类方法实现
public class Person1 {
private Person1(){
}
private static class Person1create{
private static final Person1 person1=new Person1();
}
public static Person1 getPerson1() {
return Person1create.person1;
}
}
public enum Person1 {
person1;
String name=new String("ssss");
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class test {
public static void main(String[] args) {
Person1 person1 =Person1.person1;
Person1 person2=Person1.person1 ;
person1.setName("aaa");
person2.setName("bbb");
System.out.println(person1.getName());
System.out.println(person2.getName());
}
}
输出结果都为bbb
总结:相对来说 懒汉式 (优化二),加锁方法,静态内部类,枚举等方法是比较好的方法。