单利模式:
- 在java中有23种设计模式
- 设计时构造函数要设为私有的
- 访问时要提供一个全局的访问点
单例类 - 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
场景:一个类可以定义无数个对象,但是只能有一个实例
饿汉式单利模式
指全局的单例实例在类装载时构建
class MySingleTon1{
private static MySingleTon1 singleTon = new MySingleTon1();
private MySingleTon1(){
System.out.println("MySingleTon().init");
}
//提供一个全局访问点
public static MySingleTon1 getInstance(){
return singleTon;
}
}
懒汉式单利模式
指全局的单例实例在第一次被使用时构建
线程安全的单利模式(synchronized)
线程安全---->是否竞态条件----->临界区代码段------>原子性操作------>加锁(互斥,自旋锁,读写锁)
class MySingleTon {
private static Object lock = new Object();
private static MySingleTon singleTon = null;
private MySingleTon() {
System.out.println("MySingleTon().init");
}
//提供一个全局的访问点
public static MySingleTon getInstance() {
// 1.===================
//单线程可以,但是多线程时会创建多个对象,不符合设计思想
if(singleTon ==null){
singleTon = new MySingleTon();
// 2.====================
//多线程可以,但是对单线程加锁和释放锁浪费资源
synchronized (lock){
if (singleTon = null){
singleTon = new MySingleTon();
}
}
// 3.=============================
//单线程可以,但是对多线程来说创建对象至少要执行两次
if(singleTon == null){
synchronized (lock){
singleTon = new MySingleTon();
}
}
//4.===========================
//double-checked locking 双重检验
//单线程多线程都ok
//可重入函数===》线程安全的函数
if (singleTon == null) {
synchronized (lock) {
if (singleTon == null) {
singleTon = new MySingleTon();
}
}
}
return singleTon;
}
}
public class Demo5 {
public static void main(String[] args) {
MySingleTon mySingleTon = MySingleTon.getInstance();
System.out.println(mySingleTon);
}
}
静态内部类实现单利模式
class MySingleTon3{
private MySingleTon3(){
System.out.println("MySingleTon().init");
}
//只有访问静态内部类时才会创建对象
private static class SingleTon{
public static MySingleTon3 c = new MySingleTon3();
}
public static MySingleTon3 getInstance(){
return SingleTon.c;
}
}