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

抄袭网站案例网站维护是什么职业

抄袭网站案例,网站维护是什么职业,做网站要买什么类型云空间,怎么建设QQ网站目录 一、关于设计模式 二、单例模式是什么 2.1 饿汉模式 2.2 懒汉模式 三、单例模式和多线程 3.1 饿汉模式 3.2 懒汉模式 一、关于设计模式 单例模式是一种设计模式,说它之前先来聊聊设计模式是什么。 设计模式,类似于于棋谱(大佬把…

目录

一、关于设计模式

二、单例模式是什么

2.1 饿汉模式

2.2 懒汉模式

三、单例模式和多线程

3.1 饿汉模式

 3.2 懒汉模式


 

一、关于设计模式

单例模式是一种设计模式,说它之前先来聊聊设计模式是什么。

设计模式,类似于于棋谱(大佬把一些对局整个推演过程写出来)

设计模式,就相当于程序员的棋谱。大佬们把一些典型的问题场景,整理出来,并且针对这些场景,代码该怎么写,具体方案给出一些指导和建议。

框架是属于‘硬性要求’,设计模式是‘软性要求’,目标是一致的。

二、单例模式是什么

单例模式是设计模式中经典也是比较简单的模式

单个实例(对象)

强制要求,某个类,在某个程序中,只有唯一一个实例(不允许创建多个实例,不允许new多次)

class Test{}//对象/实例
Test t = new Test();

单例模式,强制要求一个类不能创建多个对象,通过一些编程技巧,达成上述的强制要求。

在代码中,如果创建多个实例,直接编译失败

单例模式两种情况:饿汉模式和懒汉模式。接下来会根据这两种情况进行展开

2.1 饿汉模式

饿,代表着迫切,想要尽早创建实例

class Singleton{//静态成员的初始化,是在类加载的阶段出发的//类加载往往就是在程序已启动就会触发private static Singleton instance = new Singleton();//后续通过get方法获取这里的实例public static Singleton getInstance(){return instance;}//单例模式中的“点睛之笔”,在外面进行new操作,都会编译失败private Singleton() {}
}public class demo1 {public static void main(String[] args) {Singleton t1 = Singleton.getInstance();Singleton t2 = Singleton.getInstance();System.out.println(t1 == t2);//会报错//Singleton t3 = new Singleton();}
}

2.2 懒汉模式

懒 和 饿 是相对的,懒是尽量晚的创建实例(甚至可能不创建了),延迟创建

懒 在计算机里是褒义词,另一个含义,是高效率

//懒汉模式
class SingletonLazy{private static volatile SingletonLazy instance = null;public static SingletonLazy getInstance() {if(instance == null){instance = new SingletonLazy();}return instance;}private SingletonLazy(){}
}public class demo2 {public static void main(String[] args) {SingletonLazy t1 = SingletonLazy.getInstance();SingletonLazy t2 = SingletonLazy.getInstance();System.out.println(t1 == t2);//SingletonLazy t3 = new SingletonLazy();}
}

三、单例模式和多线程

上述内容,都是引子,接下来才是正题

上述懒汉/饿汉模式,是否是线程安全?如果不是,该咋办?

这两个版本的getInstance在多线程环境下调用,是否会出bug?

我们可以一个个来看

3.1 饿汉模式

class Singleton{private static Singleton instance = new Singleton();public static Singleton getInstance(){return instance;}private Singleton() {}
}

这里只涉及了 return,而return是 读操作,线程安全

String 不可变对象,天然线程安全

 3.2 懒汉模式

class SingletonLazy{private static volatile SingletonLazy instance = null;public static SingletonLazy getInstance() {if(instance == null){instance = new SingletonLazy();}return instance;}private SingletonLazy(){}
}

if(instance == null){

        instance = new SingletonLazy();

}

这部分可能会涉及到 多线程 的修改

= 操作是原子的, +=  -=  这些是非原子的

这里可能会出现bug,这就导致懒汉模式这个写法,getInstance方法是线程不安全的。

怎么解决?

加锁是一个常规的操作

但也要注意加锁的位置,我们希望的是:

条件和修改都能打包成原子的操作

private static Object locker = new Object(); public static SingletonLazy getInstance() {synchronized(locker){if(instance == null){instance = new SingletonLazy();}}return instance;}

不是写了synchronized,代码就一定安全,一定得具体问题具体分析

引入加锁后,后执行的线程就会在加锁位置阻塞,阻塞到前一个线程解锁,当后一个线程进入条件的时候,前一个线程已经修改完毕,Instance不再为null,就不会进行后续new的操作。

也可以进行方法加锁

    public synchronized static SingletonLazy getInstance() {if(instance == null){instance = new SingletonLazy();}return instance;}

但是

加锁引入新的问题:

当把实例创建好之后,后续再调用getInstance,此时都是直接执行return,如果只是进行if判定+return,纯粹的读操作了,读操作不涉及线程安全问题

但是,每次调用上述方法,都会触发一次加锁操作,虽然不涉及线程安全问题,但是多线程情况下,这里的加锁,就会相互阻塞,影响程序的执行效率

所以我们可以这样:按需加锁

真正涉及到线程安全的时候,再加锁,不涉及的时候,就不加锁

如果实例已经创建过了,就不涉及线程安全问题提。如果还没创建,就涉及线程安全问题

public static SingletonLazy getInstance() {if(instance == null){ // 判断是否需要加锁synchronized (locker){ // if(instance == null){ // 判断是否需要new对象instance = new SingletonLazy();}}}return instance;
}

单线程中,连续两个相同的if,是毫无意义的,单线程中,执行流就只有一个,上一个if和下一个if是一样的

但是多线程中,两次判定之间,可能存在其他线程,就把if中的Instance变量给修改了,也就是导致了这里的两次if的结论可能不同

再仔细分析,上述代码,仍然存在问题:

t1线程在读取Instance的时候,t2线程进行修改,是否存在内存可见性问题?

可能存在,编译器优化这件事情,非常复杂

为了稳妥起见,可以给Instance直接加上一个volatile,从根本上杜绝,内存可见性问题


private static volatile SingletonLazy instance = null;

这里更关键的问题是:指令重排序

指令重排序也是编译器优化的一种体现形式,编译会在逻辑不变的前提下,调整代码执行的先后顺序,以达到提升性能的效果

编译器优化,往往不只是javac(Java语言的编译器,Java Compile)通常是javac和jvm配合的效果(甚至是操作系统也要配合)

instance = new SingletonLazy();

实例化对象,通常包括以下三个步骤:

  1. 申请内存空间

  2. 在空间上构造对象(初始化)

  3. 内存空间的首地址,赋值给引用变量

正常来说,这三个步骤,是按照1 2 3 这样的步骤来执行的

但是,在指令重排序下,可能是 1 3 2这样的顺序

单线程下1 2 3还是1 3 2 其实无所谓

如果是1 3 2 这样的顺序执行,多线程下 是会出现bug的

对应的解决方法也要用到 volatile,并且上面也碰巧把这个问题解决了:

 private static volatile SingletonLazy instance = null;

Volatile 的功能有两方面:

  1. 确保每次独缺操作,都是读内存 内存可见性

  2. 关于该变量的读取和修改操作,不会触发重排序

http://www.dtcms.com/a/400240.html

相关文章:

  • 企业网站建设北京南充市房地产网官方网站
  • 全面掌握 Py2neo 与 Neo4j:从容器化部署到高级应用实战
  • 网站的简介怎么在后台炒做网站数据库空间大小
  • 合肥网站建设公司代理备案公司网站建设方案书
  • 网站流量 钱免费软件下载公众号
  • 为什么单片机的外接晶振要并连两个电容?
  • html5手机商城网站模板代做毕业设计的网站好
  • 网站做多个镜像如何结合搜索检索与seo推广
  • 接口自动化测试 - requests 库
  • 昆明快速建站模板互联网项目有哪些
  • 用dw建设个人网站视频创建网站步骤
  • 今鼎网站建设wordpress打开页面很慢
  • vite与axios如何配置多个接口域名支持跨域,若依配置为例
  • 商城网站备案需要什么美容公司网站什么做才好
  • 安科瑞变电所运维云平台:人力优化与安全保障的智慧解决方案
  • 建设个网站从哪里盈利科普重庆网站
  • LeetCode 1578.使绳子变成彩色的最短时间
  • 浙江常升建设有限公司网站打开网站弹出qq
  • 牛二网站建设上海环球金融中心电梯
  • RNA-seq分析之TMB分析(TCGA版)
  • 网易云网站开发深圳东门买衣服攻略
  • 广州手机网站定制如何怎么开一个做网站的工作室
  • TDengine 统计函数 PERCENTILE 用户手册
  • 卡片式设计 网站wordpress 会议主题
  • 对于ICP而言 主要承担网站信息怎样把广告放到百度
  • 网站开发电商wordpress tag云显示数量
  • 沭阳网站开发抖音seo点击软件排名
  • 页面设计术语祁阳seo
  • 玳瑁的嵌入式日记---0923(ARM)
  • 论文阅读-Adaptive Multi-Modal Cross-Entropy Loss for Stereo Matching