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

网站移动端优化工具乐清柳市阿里巴巴做网站的

网站移动端优化工具,乐清柳市阿里巴巴做网站的,响应式网站和自适应,网站开发架构多线程带来的的风险-线程安全 ~~ 多线程编程中,最难的地方,也是一个最重要的地方#xff0c;还是一个最容易出错的地方,更是一个面试中特别爱考的地方.❤️❤️❤️ 线程安全的概念 万恶之源,罪魁祸首是多线程的抢占式执行,带来的随机性.~~#x1f615;#x1f615;… 多线程带来的的风险-线程安全 ~~ 多线程编程中,最难的地方,也是一个最重要的地方还是一个最容易出错的地方,更是一个面试中特别爱考的地方.❤️❤️❤️ 线程安全的概念 万恶之源,罪魁祸首是多线程的抢占式执行,带来的随机性.~~ 如果没有多线程,此时程序代码执行顺序就是固定的,代码顺序固定,程序的结果就是固定的. 如果有了多线程,此时在抢占式执行下,代码执行的顺序,会出现更多的变数!!! 代码执行顺序的可能性就从一种情况变成无数种情况!!! 所以就需要保证这无数种线程调度顺序的情况下,执行的结果都是正确的!!!只要是有一种情况下,代码结果不正确,就视为线程不安全!!! 问题来了:能否消除这样的随机性了? 调度的源头来自于操作系统的内核实现. 1.作为程序猿的我们改不了. 2.即使改了自己的操作系统,也无法推广开来,因为全世界大多数操作系统都是这样的,已成定局! 观察线程不安全(代码) class Counter{public int count 0;public void add(){count;} } public class ThreadDemo13 {public static void main(String[] args) {Counter counter new Counter();// 创建两个线程, 两个线程 counter 来调用 5W 次的add方法Thread t1 new Thread(()-{for (int i 0; i 5_0000; i) {counter.add();}});Thread t2 new Thread(()-{for (int i 0; i 5_0000; i) {counter.add();}});// 启动线程t1.start();t2.start();// 等待两个线程结束try {t1.join();t2.join();} catch (InterruptedException e) {throw new RuntimeException(e);}// 打印最终的 count 值 预期结果: count 10WSystem.out.println(count counter.count);} }运行结果: 我们的需求是两个线程各自自增 5w次,一共自增 10w次, 预期结果是 10w,实际结果不是 10w而且每次都不一样. 程序出现了bug(程序不符合需求,就是bug). 注:这个就是典型的线程安全问题!!! 线程不安全的原因 ~~ 为什么程序就出现了这个情况? 线程与指令之间的关系: 一个线程要执行,就需要先编译成很多的CPU指令,写的任何一个代码都是要编译成很多的CPU指令的!!! 个人理解:一个线程是来完成一个任务,要做一些工作,而这个工作是可以分解成一个一个的小步骤的,每个小步骤就是一个指令. 由于线程的抢占式执行,导致当前执行到任意一个指令的时候,线程都有可能被调度走,然后CPU让别的线程来执行. 寄存器,CPU里重要的组成部分,寄存器也能存数据,空间更小,访问速度更快,CPU进行的运算都是针对寄存器(准确的说,是通用寄存器,如EAX,EBX,ECX)中的数据进行的 count; 操作本质上要分成三步 1.先把内存中的值,读取到CPU的寄存器中 ~~load 2.把CPU寄存器里的数值进行 1运算 ~~add 3.把得到的结果写回到内存中 ~~ save 注:load,add,save就是CPU上执行的三个指令(被视为机器语言). 两个线程并发的执行count,此时就相当于两组load,add,save进行执行,此时不同的线程调度顺序就可能会产生一些结果上的差异. **作图来理解多线程的调度:**❤️❤️❤️ 分析执行过程: 思考一下: 出现bug 之后,得到的结果一定是 10w, 结果是一定 5w 嘛? 极端情况下,所有的执行都是交错执行,是否就是 5w 呢?? 实际上,结果是可以小于 5w ,只是概率更低了!! 根结底线程安全问题全是因为线程的无序调度(罪魁祸首,万恶之源)导致了执行顺序不确定结果就变化了!!! 总结(线程不安全的原因) [根本原因] 抢占式执行,随机调度 ~~ 对此,我们无能为力. 代码结构: 多个线程 同时 修改 同一个变量 ~~ 不安全!!! 一个线程,修改一个变量,安全. 多个线程读取同一个变量,安全. 多个线程修改多个不同的变量,安全. 注1: 因此可以通过代码结构来规避这个线程不安全问题, 但是因为需求问题,代码结构无法进行调整(这种方法使用频率并不高). 注2: 修改 不可变对象是无法修改的,天然就是线程安全的!!! 原子性. 如果修改操作是原子的,出现问题概率小;如果是非原子的,出现问题概率极高(线程不安全问题,其实本质上是事务的脏读问题,之前博主写的博客解释过相关概念,在此不做解释啦!ヾ(❀^ω^) 原子: 不可拆分的基本单位. 上述 count 操作就不是原子,里面可以拆分成三个操作,load,add,save.某个操作,对应单个CPU指令,就是原子的,如果这个操作对应多个CPU指令,大概率就不是原子的.比如直接使用 赋值,就是一个原子的操作 内存可见性,引起的线程不安全 一个线程读,一个线程改,可能出现读的结果和预期不符合的问题. 指令重排序,引起的线程不安全 本质上是编译器优化,优化出bug了.优化:编译器觉得程序猿写的代码太low了,对代码进行调整,在保持代码逻辑不变的情况下,调整代码的执行顺序,从而加快程序的执行效率. 线程不安全问题的解决 **如何解决线程不安全问题?** 最主要的手段就是从这个原子性下手,通过加锁不能把非原子的操作变成原子的. 即解决前面代码的线程不安全问题,就是通过加锁让count变成原子的. synchronized public void add(){ count; } 加了 synchronized 之后,进入方法就会加锁,出了方法就会解锁. 如果两个线程同时尝试加锁,此时一个能获取锁成功,另一个只能阻塞等待(处于BLOCKED状态),一直阻塞到刚才的状态解锁(释放锁),当前线程才能加锁成功!!! 操作系统的基本设定,系统里的锁“不可剥夺”特性,一旦一个线程获取到锁,除非它主动释放,否则无法强占. 加锁,说是保证原子性,不是让load,add,save三个操作一次完成,也不是就是让其它也想操作的线程阻塞等待了 虽然加锁之后,算得慢了,但是还是比单线程要快,加锁只是针对count加锁了,除了count之外,还有for循环的代码,for循环代码是可以并发执行的(线程t1和线程t2各自修改各自for循环的局部变量i,是没问题的),只是count串行执行了. 一个任务中,一部分可以并发,一部分串行,仍然是比所有代码串行要快的. 加锁,是要明确执行对哪个对象加锁的.如果两个线程针对同一个对象加锁,会产生阻塞等待(锁竞争/锁冲突),如果两个线程针对不同对象加锁,不会阻塞等待(不会锁冲突/锁竞争). synchronized的使用方法 修饰方法 修饰普通方法 进入方法就加锁,离开方法就解锁 修饰静态方法 通理也是这样,进入方法就加锁,离开方法就解锁 但是这两种修饰方法,加锁的“对象”不同,修饰普通方法,锁对象就是this,修饰静态方法,锁对象就是类对象. 修饰代码块 显示/手动指定锁对象
http://www.yayakq.cn/news/2276/

相关文章:

  • 克隆网站模板重庆网站建设公司招聘
  • 免费下载建设银行官方网站下载做标签这个网站刷单安全吗
  • 简单免费自建网站365网站建设
  • 门户建设网站多少钱酒店网站如何做
  • 做产品网站信息网站制作
  • 厦门制作企业网站哈尔滨 网站建设公司
  • 做外贸网站哪家效果好wordpress当中加入论坛
  • 上海网站推广找哪家手车做网课网站多少
  • 免费网站模板软件如何寻找客户
  • 静态网站可以做哪些内容c 网站开发平台
  • 发帖那个网站好 做装修的thinkcmf和wordpress
  • 专业外贸网站制作dw网页设计代码模板源代码
  • 专业集团门户网站建设服务商网站后台建设计划书
  • 广陵建设局网站做网做网站建设的网站
  • 网站开发前景好吗海南创想
  • 百度怎么收录我的网站赣州章贡区
  • 上海网站建设服务公司网站锚文本
  • 手机回收站找客户资源的软件
  • 青海省住房和城乡建设局网站首页公司网络规划与设计
  • 米托网站建设什么是网络社交安全
  • 制作app软件多少钱网站seo查询站长之家
  • 点击宝seo企业网站优化
  • 有专门做试吃的网站吗国际网站排名查询
  • 汽车配件外贸网站wordpress下载整站源码
  • 郑州网站建设推广优化网络营销中网站的目的是
  • 我想创建一个网站广州做网站优化费用
  • 动漫网站策划书无锡微信网站推广
  • 淘宝联盟推广网站怎么做wordpress不显示中文图片不显示
  • 郑州网站建设方案wordpress先页面再首页
  • 安徽省建设厅八大员报名网站深圳公司名称核准查询