当前位置: 首页 > news >正文

做网站软件ps网站搭建三部曲是什么?

做网站软件ps,网站搭建三部曲是什么?,wordpress怎么离线修改主页页脚,wordpress 去掉rss单例模式 单例模式使用场景 ​ 什么是单例模式?保障一个类只能有一个对象(实例)的代码开发模式就叫单例模式 ​ 什么时候使用? 工具类!(一种做法,所有的方法都是static,还有一种单…

单例模式

单例模式使用场景

​ 什么是单例模式?保障一个类只能有一个对象(实例)的代码开发模式就叫单例模式
​ 什么时候使用? 工具类!(一种做法,所有的方法都是static,还有一种单例模式让工具类只有一个实例) 某类工厂(SqlSessionFactory)

实现方式

1. 饿汉

/*** 饿汉模式(迫切加载)*/
public class Singleton01 {//构造私有化private Singleton01(){}//2 创建一个private对象private static final Singleton01 INSTANCE = new Singleton01();//这个地方就体现饿汉,一来就创建对象给他//3 提供一个static方法来获取你的这个单实例对象public static Singleton01 newInstance(){return INSTANCE;}
}

测试代码

public class MyTest {public static void main(String[] args) {Singleton01 singleton01 = Singleton01.newInstance();Singleton01 singleton02 = Singleton01.newInstance();System.out.println(singleton01.equals(singleton02));}
}

输出为true说明两个对象是相同的

2. 懒汉(懒汉太懒了,要用的时候才能创建。)

/*** 懒汉模式(懒加载) 单线程*/
public class Singleton02 {private Singleton02() {}//2 创建一个private对象private static Singleton02 INSTANCE;//3 提供一个static方法来获取你的这个单实例对象 只适合在单线程中public static Singleton02 newInstance() {if(INSTANCE == null){INSTANCE = new Singleton02()}return INSTANCE;}
}

测试代码

public class MyTest {public static void main(String[] args) {Singleton02 singleton03 = Singleton02.newInstance();Singleton02 singleton04 = Singleton04.newInstance();System.out.println(singleton03.equals(singleton04));}
}

输出为true说明两个对象是相同的
懒汉模式 只要不调用newInstance()方法 INSTANCE就一直为空 只用调用了才会创建

测试代码(如果多线程 就不是单例了)

public class MyTest {public static void main(String[] args) {for (int i = 0; i < 10; i++) {new Thread(() -> Singleton02.newInstance()).start();}}
}

运行结果
在这里插入图片描述

说明有不同的线程都调用到了构造方法
解决方法:加锁
1.方法上加锁
public static synchronized Singleton02 newInstance()
缺点:锁住整个方法 里面还有业务逻辑 效率降低很多
2.synchronized代码块

/*** 懒汉模式(懒加载)*/
public class Singleton02 {private Singleton02() {}//2 创建一个private对象private static Singleton02 INSTANCE;//3 提供一个static方法来获取你的这个单实例对象//方案1:方法锁,里面还有业务逻辑//public static synchronized  Singleton02 newInstance(){public static Singleton02 newInstance() {//方案2:锁代码块//synchronized (Singleton02.class){ // 100个线程哪怕有一个已经创建了也要排队if (INSTANCE == null) {//多线程来了? T1 T2synchronized (Singleton02.class) {if (INSTANCE == null) {INSTANCE = new Singleton02();}}}//}//此处有10W行代码....return INSTANCE;}//普通方法public String getConnection() {return "I am connection!";}
}

在这里插入图片描述

只会有一个线程调用到构造方法

写到这里是不是觉得单例模式已经可以了?
但是这个代码也不是绝对安全的,不绝对是单例 利用反射去创建类的对象可以将单例进行破坏 写个测试代码

public class MyTest {
public static void main(String[] args) throws Exception{//正常获取Singleton02 instance = Singleton02.newInstance();//通过反射获取Class<? extends Singleton02> aClass = instance.getClass();//注意:构造方法是私有的Constructor<? extends Singleton02> declaredConstructor = aClass.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);Singleton02 instance02 = declaredConstructor.newInstance();System.out.println(instance);System.out.println(instance02);}
}

在这里插入图片描述

生成了两个对象,说明已经通过反射将单例破坏掉了

修改代码

/*** 懒汉模式(懒加载)*/
public class Singleton02 {private Singleton02() {synchronized (Singleton02.class) {if (INSTANCE != null){throw new RuntimeException("防止反射破坏单例");}}}//2 创建一个private对象private static Singleton02 INSTANCE;//3 提供一个static方法来获取你的这个单实例对象//方案1:方法锁,里面还有业务逻辑//public static synchronized  Singleton02 newInstance(){public static Singleton02 newInstance() {//方案2:锁代码块//synchronized (Singleton02.class){ // 100个线程哪怕有一个已经创建了也要排队if (INSTANCE == null) {//多线程来了? T1 T2synchronized (Singleton02.class) {if (INSTANCE == null) {INSTANCE = new Singleton02();}}}//}//此处有10W行代码....return INSTANCE;}//普通方法public String getConnection() {return "I am connection!";}
}

在这里插入图片描述

那到这一步反射就不能搞破坏了吗?
答案是可以的 为什么?
因为第一次创建的时候使用的是正常的方式肯定会调用构造方法
将第一个打印放到反射创建之前就会打印出第一个的对象 第二次通过反射再拿一个对象就不行 如果我两次都使用反射来获取对象

public class MyTest {
public static void main(String[] args) throws Exception{
Class<? extends Singleton02> aClass = Singleton02.class;//注意:构造方法是私有的Constructor<? extends Singleton02> declaredConstructor = aClass.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);Singleton02 instance01 = declaredConstructor.newInstance();Singleton02 instance02 = declaredConstructor.newInstance();System.out.println(instance01);System.out.println(instance02);}
}

在这里插入图片描述

ok 单例又被破坏
还有没有其他方法?
不管是反射还是正常都会调用构造方法 那就先搞一个字段flag来进行校验

package org.jhy._01singleton;/*** 懒汉模式(懒加载)*/
public class Singleton02 {private static Boolean flag = false;private Singleton02() {
//        synchronized (Singleton02.class) {
//            if (INSTANCE != null){
//                throw new RuntimeException("防止反射破坏单例");
//            }
//        }if (flag == false) {flag = true;} else {throw new RuntimeException("防止反射破坏单例");}}//2 创建一个private对象private static Singleton02 INSTANCE;//3 提供一个static方法来获取你的这个单实例对象//方案1:方法锁,里面还有业务逻辑//public static synchronized  Singleton02 newInstance(){public static Singleton02 newInstance() {//方案2:锁代码块//synchronized (Singleton02.class){ // 100个线程哪怕有一个已经创建了也要排队if (INSTANCE == null) {//多线程来了? T1 T2synchronized (Singleton02.class) {if (INSTANCE == null) {INSTANCE = new Singleton02();}}}//}//此处有10W行代码....return INSTANCE;}//普通方法public String getConnection() {return "I am connection!";}
}
public class MyTest {
public static void main(String[] args) throws Exception{
//通过反射获取Class<? extends Singleton02> aClass = Singleton02.class;//注意:构造方法是私有的Constructor<? extends Singleton02> declaredConstructor = aClass.getDeclaredConstructor(null);declaredConstructor.setAccessible(true);Singleton02 instance01 = declaredConstructor.newInstance();//获取字段名Field flag = aClass.getDeclaredField("flag");flag.setAccessible(true);//获取之后复位 认为又是第一次flag.set(instance01,false);Singleton02 instance02 = declaredConstructor.newInstance();System.out.println(instance01);System.out.println(instance02);}
}

在这里插入图片描述

ok,单例又被破坏了
那么反射真的就无所不能了吗???

让我们来看看newInstance()这个方法的源码
在这里插入图片描述

不能通过反射创建枚举的对象,所以用枚举就能防止反射破坏单例

public enum Singleton03 {INSTANCE;public void testMethod(){System.out.println("执行了单例类的方法");}
}// Test.java
class Test {public static void main(String[] args) {//演示如何使用枚举写法的单例类Singleton03.INSTANCE.testMethod();System.out.println(Singleton03.INSTANCE);Singleton03 instance01 = Singleton03.INSTANCE;Singleton03 instance02 = Singleton03.INSTANCE;System.out.println(instance01.equals(instance02));}
}

结果显然为true 而且枚举类里面就不能用反射的方法 枚举里面只有一个实例那就是单例

http://www.yayakq.cn/news/370712/

相关文章:

  • 中国建设银行北京天竺支行网站消费全返的 微网站开发
  • 做网站公司 备案wordpress 直播 视频
  • 杭州手机模板建站在线制作图片头像
  • 网站运营与管理的一个目的襄阳公司网站建设
  • 兰州工程建设信息网站.net 网站管理系统
  • 网站跳转怎么解释网站建设禁止性规定
  • 怎样围绕网站专题发展来做ppt建设网站怎么添加端口映射
  • 网站如何做分站系统贵阳网站建设服务
  • 呼市做引产z首大网站安徽省建设厅网站个人怎么注册
  • 网站建设鼠标滑动效果软文范例大全500字
  • 做网站要不要35类商标东莞互联网大公司有哪些
  • 阳泉市建设局网站营销广告语
  • 大兴做网站公司网络营销推广方式都有哪些
  • 怎么做彩票网站平台weex做的网站
  • 临清网站建设价格wordpress 文章页 tag
  • 怎么做企业网站原型什么是网站建设技术
  • 佛山建站佛山网页设计wordpress图片主题
  • .net mvc做网站什么网站可以做兼职美工
  • 扬州公司做网站网页设计师培训水公司
  • 徐州网站建设哪家专业南阳手机网站制作
  • 手机qq网页版网站怎么做网页上小广告
  • 绵阳网站排名网站访问速度 云组机
  • 江苏省建设工程设计施工图审核中心网站广告设计软件photoshop
  • ppt 做的最好的网站wordpress怎么显示摘要
  • 申请一个自己的网站51免费模板网
  • 用php做购物网站友情链接检查
  • 麻城建设局网站停办做建材网站
  • 上海技术公司做网站文件上传网站源码
  • 阿里服务器怎么做网站服务器吗如何让自己的网站被百度收录
  • 如何设计网站首页导航微信公众号网页版入口