生活工程体验信仰哲学精神
投稿投诉
精神世界
探索历史
哲学文学
艺术价值
信仰创造
境界审美
体验技术
技能工具
工程信息
医学生产
生活运用
操作能力

做多线程并发扩展,这两点你需要关注

10月2日 红朱砂投稿
  摘要:Spring作为一个IOCDI容器,帮助我们管理了许许多多的bean。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。
  本文分享自华为云社区《【高并发】多线程并发扩展云社区华为云》,作者:冰河。死锁死锁必要条件
  1)互斥条件
  进程对所分配到的资源进行排他性的使用,即在一段时间内某个资源只由一个进程占用,如果此时还有其他进程请求资源,那么请求者只能等待,直到占用资源的进程将资源释放。
  2)请求和保持条件
  进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有。此时,请求进程阻塞,但又对自己已获得的其他资源保持不放。
  3)不剥夺条件
  进程已获得资源,在未使用完之前,不能被剥夺,只能在使用完后,自己释放相应的资源。
  4)环路等待条件
  存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被链中下一个进程所请求。
  死锁示例代码如下:packageio。binghe。concurrency。example。importlombok。extern。slf4j。Slf4j;authorbingheversion1。0。0description一个简单的死锁类当DeadLock类的对象flag1时(td1),先锁定o1,睡眠500毫秒而td1在睡眠的时候另一个flag0的对象(td2)线程启动,先锁定o2,睡眠500毫秒td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定;td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定;td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。Slf4jpublicclassDeadLockimplementsRunnable{publicintflag1;静态对象是类的所有对象共享的privatestaticObjecto1newObject(),o2newObject();Overridepublicvoidrun(){log。info(flag:{},flag);if(flag1){synchronized(o1){try{Thread。sleep(500);}catch(Exceptione){e。printStackTrace();}synchronized(o2){log。info(1);}}}if(flag0){synchronized(o2){try{Thread。sleep(500);}catch(Exceptione){e。printStackTrace();}synchronized(o1){log。info(0);}}}}publicstaticvoidmain(String〔〕args){DeadLocktd1newDeadLock();DeadLocktd2newDeadLock();td1。flag1;td2。flag0;td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。td2的run()可能在td1的run()之前运行newThread(td1)。start();newThread(td2)。start();}}
  注意:代码为转载示例处理死锁的方法预防死锁:通过设置某些限制条件,去破坏产生死锁的四个必要条件中的一个或几个条件,来防止死锁的发生。避免死锁:在资源的动态分配过程中,用某种方法去防止系统进入不安全状态,从而避免死锁的发生。检测死锁:允许系统在运行过程中发生死锁,但可设置检测机构及时检测死锁的发生,并采取适当措施加以清除。解除死锁:当检测出死锁后,便采取适当措施将进程从死锁状态中解脱出来。多线程并发最佳实践
  (1)使用本地变量
  尽量使用本地变量,而不是创建一个类或实例的变量
  (2)使用不可变类
  比如:String、基础类型的包装类等,一旦创建就不会改变,不可变类可以降低代码中需要的同步数量。
  (3)最小化锁的作用域范围:S1(1aan)
  a:并行计算部分所占的比例
  n:并行处理的节点个数
  S:加速比
  当a1时,没有串行,只有并行,此时,Sn
  当a0时,只有串行,没有并行,此时,S1
  当n趋向于无穷大时,S趋向于1(1a),这也是加速比S的上限
  S1(1aan)公式也叫做:阿姆达尔定律或者安达尔定理。
  (4)使用线程池的Executor,而不是直接newThread执行
  (5)宁可使用同步也不要使用线程的wait和notify
  (6)使用BlockingQueue实现生产消费模式
  (7)使用并发集合而不是加了锁的同步集合
  (8)使用Semaphore创建有界的访问
  (9)宁可使用同步代码块,也不使用同步的方法
  (10)避免使用静态变量Spring与线程安全性
  (1)弹簧豆:范围有两个取值:单例、prototype
  (2)交由Spring管理大多数是无状态对象,这种不会因为多线程而导致状态被破坏的对象很适合Spring的默认scopesingleton,每个单例的无状态对象都是线程安全的。其实只要是无状态的对象,不管是单例还是多例,都是线程安全的。实际上,Spring没有保证bean的线程安全
  Spring作为一个IOCDI容器,帮助我们管理了许许多多的bean。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。
  Spring对每个bean提供了一个scope属性来表示该bean的作用域。它是bean的生命周期。例如,一个scope为singleton的bean,在第一次被注入时,会创建为一个单例对象,该对象会一直被复用到应用结束。
  singleton:默认的scope,每个scope为singleton的bean都会被定义为一个单例对象,该对象的生命周期是与SpringIOC容器一致的(但在第一次被注入时才会创建)。在整个SpringIoC容器里,只有一个bean实例,所有线程共享该实例。
  prototype:bean被定义为在每次注入时都会创建一个新的对象。每次请求都会创建并返回一个新的实例,所有线程都有单独的实例使用,这种方式是比较安全的,但会消耗大量内存和计算资源。
  request(请求范围实例):bean被定义为在每个HTTP请求中创建一个单例对象,也就是说在单个请求中都会复用这一个单例对象。每当接受到一个HTTP请求时,就分配一个唯一实例,这个实例在整个请求周期都是唯一的。
  session(会话范围实例):bean被定义为在一个session的生命周期内创建一个单例对象。在每个用户会话周期内,分配一个实例,这个实例在整个会话周期都是唯一的,所有同一会话范围的请求都会共享该实例。
  application:bean被定义为在ServletContext的生命周期中复用一个单例对象。
  websocket:bean被定义为在websocket的生命周期中复用一个单例对象。
  globalsession(全局会话范围实例):这与会话范围实例大部分情况是一样的,只是在使用到portlet时,由于每个portlet都有自己的会话,如果一个页面中有多个portlet而需要共享一个bean时,才会用到。
  我们交由Spring管理的大多数对象其实都是一些无状态的对象,这种不会因为多线程而导致状态被破坏的对象很适合Spring的默认scope,每个单例的无状态对象都是线程安全的(也可以说只要是无状态的对象,不管单例多例都是线程安全的,不过单例毕竟节省了不断创建对象与GC的开销)。
  无状态的对象即是自身没有状态的对象,自然也就不会因为多个线程的交替调度而破坏自身状态导致线程安全问题。无状态对象包括我们经常使用的DO、DTO、VO这些只作为数据的实体模型的贫血对象,还有Service、DAO和Controller,这些对象并没有自己的状态,它们只是用来执行某些操作的。例如,每个DAO提供的函数都只是对数据库的CRUD,而且每个数据库Connection都作为函数的局部变量(局部变量是在用户栈中的,而且用户栈本身就是线程私有的内存区域,所以不存在线程安全问题),用完即关(或交还给连接池)。
  有人可能会认为,我使用request作用域不就可以避免每个请求之间的安全问题了吗?这是完全错误的,因为Controller默认是单例的,一个HTTP请求是会被多个线程执行的,这就又回到了线程的安全问题。当然,你也可以把Controller的scope改成prototype,实际上Struts2就是这么做的,但有一点要注意,SpringMVC对请求的拦截粒度是基于每个方法的,而Struts2是基于每个类的,所以把Controller设为多例将会频繁的创建与回收对象,严重影响到了性能。
  线程安全问题都是由全局变量及静态变量引起的
  若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步,否则就可能影响线程安全。
  线程安全的几种情况:
  1)常量始终是线程安全的,因为只存在读操作。
  2)每次调用方法前都新建一个实例是线程安全的,因为不会访问共享的资源。
  3)局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量和方法内变量。
  总之,Spring根本就没有对bean的多线程安全问题做出任何保证与措施。对于每个bean的线程安全问题,根本原因是每个bean自身的设计没有在bean中声明任何有状态的实例变量或类变量,如果必须如此,那么就使用ThreadLocal把变量变为线程私有的,如果bean的实例变量或类变量需要在多个线程之间共享,那么就只能使用synchized、lock、CAS等这些实现线程同步的方法了。
  点击下方,第一时间了解华为云新鲜技术
  华为云博客大数据博客AI博客云计算博客开发者中心华为云
投诉 评论

拒绝退役!昔日国乒天才剑指全运会,13岁进国家队曾战胜马龙樊振东的积分成为国内乒坛热议的话题,此外国乒其他球员在近期也有新的动态。前国乒主力闫安在接受国内媒体采访时,表示虽然自己已退出国家队,但并没有结束自己的职业生涯,仍然希望继续站……刚3连跌的油价,8月或就要涨,预计上调超过120元吨现在已经来到7月底,在本月油价实现了2连跌,这让今年大涨的油价继续下降了一些,不过在进入新一轮油价调整后,油价就出现了预计上涨的情况,这让刚下跌的油价,恐怕又要涨了,各位车友还……中金,一家比腾讯工资还高的企业,人均年薪高达115万元最近,中金这家企业算是彻底火了,只因员工工资比互联网大厂腾讯都高,可能有不少人不太了解,对此事的来龙去脉不太清楚,心中满是问号,比如中金是一家干什么的公司?一家比腾讯公司工资还……王者荣耀中这些鲜为人知的实用小技巧你知道的有哪些?一、亚瑟的大招在释放后会有一秒左右到僵直,所以先用二技能再大招,就可以将输出最大化。在到达十一级且有冷却40的情况下,可无限加速赶路,同时也可以打出双重沉默的效果。另外亚瑟的一……郎平的三大爱徒两人已出嫁,还有一人至今仍单身中国女排是一支具有光辉历史的杰出队伍,在20世纪80年代,中国女排曾获得过辉煌的五连冠。中国女排迎接过辉煌,掉落过低谷,他们从低谷中奋起,从来没有说过放弃,面对强敌出手,……做多线程并发扩展,这两点你需要关注摘要:Spring作为一个IOCDI容器,帮助我们管理了许许多多的bean。但其实,Spring并没有保证这些对象的线程安全,需要由开发者自己编写解决线程安全问题的代码。……逆流与自由我愿岁月无负天地,我愿此生辽阔高远。熊培云《自由在高处》。条件即逆境。当人们拥有并享受某些条件时,是否会忽略条件给自己带来的麻烦。如一个手脚不健全的人,生活定不便,处处受……一个人2小时,轻松搞定5菜1汤上桌就光盘,老公孩子夸我厨艺棒大家好,这里是小慧今天说美食,今天不上班,在家给孩子还有老公做好吃的饭菜,自己一个人,用了两个小时,轻轻松松搞定了五菜一汤,一端上桌就光盘,老公和孩子都夸我我厨艺好,做法简单,……适合一个人旅行的12个地方,没有羁绊,不受约束,享受快乐时光很多人都追求双宿双飞,但是谁又能够体会到一个人的快乐呢?特别是现在社会充满诱惑的时代,如果能够一个人,那么就能享受到最无拘无束,最自由快乐的生活。如果一个人,大家想去哪里……渤海明珠天津《天津》始于隋朝大运河的开通。在南运河和北运河的交汇处,位于现在的金钢桥三岔河口,史称三会海口,是天津最早的发祥地。《天津》这个名字是永乐初年燕王朱棣所起,《为天子渡河》……美国遏华小算盘有悖国际合作共赢大趋势作者:王楚天殷强当前,中华民族伟大复兴战略大局和世界百年未有之大变局相互交织,世界形势正发生深刻复杂变化,不确定性不稳定性进一步加剧。尤为引人关注的是,美国为维系自身霸权……恒大青训终于出成果?23岁前射手王收获中超首球,挑射国门绝杀相信不少球迷都知道,在过去的十年里,中超联赛曾经有一支巨无霸球队,他们11年8夺中超冠军,其中还创造了7连冠的纪录,而且还代表中超球队两夺亚冠冠军,世俱杯也两度进入4强,成为了……
神奇的蚂蚁未平造句用未平造句大全金铲铲JSL联赛巅峰王者精彩操作盘点索尔版本如何突出重围文笔挑战黄昏是海溢出来的思念,句句都拟人化,又是谁的意难平为什么好领导不能显得太能干雅诗兰黛粉水适合年龄雅诗兰黛粉水的作用宫颈糜烂术后的护理有哪些措施呢大策略帮助孩子提高注意力老年人过性生活应不强求不压抑顺其自然2022下半年选什么手机?我只推荐这3款,满足你的所有用机需鸠摩罗什的舌头是真的吗鸠摩罗什的舌舍利是怎么回事未来的微型民宿如何设计?盘点当下最火的五个趋势夏季怎么减肥快夏季运动减肥注意事项劳动真快乐无言的爱送给懵懂的你无言的结局!宝妈必入宝宝斜颈的判断与纠正一直在流浪,却未曾见过海洋如何识别假洋酒NASA拍到我国祝融号火星车照片伪造股票债券罪的构成四要件有哪些?灵异小说排行榜前十名关于励志的名人名言公交车上小学作文300字任正非:华为反对辛苦的无效劳动

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找