1、23种设计模式
.
2、单例设计模式
单例模式可以说是大多数开发人员在实际中使用最多的,常见的Spring默认创建的bean就是单例模式的。
单例模式有很多好处,比如可节约系统内存空间,控制资源的使用。
其中单例模式最重要的是确保对象只有一个。
简单来说,保证一个类在内存中的对象就一个。
RunTime就是典型的单例设计,我们通过对RunTime类的分析,一窥究竟。
2.1、RunTime里的单例源码
public class Runtime {
//1.创建静态的全局唯一的对象
private static Runtime currentRuntime = new Runtime();
//2.私有化构造方法,不让外部来调用
/** Don't let anyone else instantiate this class */
private Runtime() {}
//3.通过自定义的静态方法获取实例
public static Runtime getRuntime() {
return currentRuntime;
}
}
创建单例模式的步骤
1、对本类无参构造函数私有化:为了不让外界通过无参构造函数随意创建对象
2、创建全局唯一的对象(static),也做私有化:不让外界通过类名.对象调用
3、自定义static修饰的公共方法返回创建的对象:static修饰-》外界可以通过类名.方法调用
3、饿汉式单例模式
饿汉式:单例类一上来就new一个对象,不管后面会不会调用。像是饿了很久
package cn.tedu.design;
/*本类用于测试单例设计模式方案1---饿汉式*/
//MySingle类里一上来就new了一个single对象,不会后面会不会用得到
import org.omg.SendingContext.RunTime;
public class TestSingle1 {
public static void main(String[] args) {
/*通过全局访问点获取单例程序的对象
* 这个对象就是单例的*/
MySingle single1 = MySingle.getMySingle();
MySingle single2 = MySingle.getMySingle();
System.out.println(single1==single2);
System.out.println(single1);
System.out.println(single2);
}
}
class MySingle{
/*1、构造方法私有化的原因:为了不让外界通过构造方法随意创建对象*/
private MySingle() {}
/*2、对象私有化的目的:是为了不让外界直接获取创建好的对象,
不被private修饰可以通过MySingle.single调用*/
private static MySingle single=new MySingle();
/*3、static修饰方法,外界通过调用 类名.方法()返回创建好的那一个single对象*/
public static MySingle getMySingle(){
return single;
}
}
4、懒汉式单例模式(面试重点)
是对饿汉式的优化,等到调用单例类的时候再创建对象,再次调用判断直接返回之前那个对象
package cn.tedu.design;
/*本类用于测试单例设计模式二----懒汉式(面试重点)*/
//不会在第一时间加载,在用到了才加载
public class TestSingle2 {
public static void main(String[] args) {
Mysingle2 s1 = Mysingle2.getSingle2();
Mysingle2 s2 = Mysingle2.getSingle2();
System.out.println(s1);
System.out.println(s2);
}
}
class Mysingle2{
private Mysingle2(){}
private static Mysingle2 single2;//在类的内部创建引用类型变量
public static Mysingle2 getSingle2(){
if (single2==null){
single2=new Mysingle2();
}
return single2;
}
}
5、三种方式解决懒汉式线程安全模式
在多线程情况下,多个线程拿到getSingle2()方法 ,同时判断single2为空,同时创建多个对象
1、在方法前面加synchronized修饰
package com.roocon.thread.t5;
public class Singleton2 {
private Singleton2(){
}
private static Singleton2 instance;
public static synchronized Singleton2 getInstance(){
if(instance == null) {//1
instance = new Singleton2();//2
}
return instance;
}
}
2、加同步代码块,减少锁的颗粒大小。
package com.roocon.thread.t5;
public class Singleton2 {
private Singleton2(){
}
private static Singleton2 instance;
public static synchronized Singleton2 getInstance(){
if(instance == null) {
synchronized (Singleton2.class){
if (instance == null){
instance = new Singleton2();
}
}
}
return instance;
}
}
3、加上volatile关键字,因为volatile可以禁止指令重排序。
package com.roocon.thread.t5;
public class Singleton2 {
private Singleton2(){}
private static volatile Singleton2 instance;
public static Singleton2 getInstance(){
if(instance == null) {
synchronized (Singleton2.class){
if (instance == null){
instance = new Singleton2();
}
}
}
return instance;
}
}