Java并发优化思路

一、并发优化

1.1、Java高并发包所采用的几个机制

(1)、CAS(乐观操作)
       jdk5以前采用synchronized,对共享区域进行同步操作,synchronized是重的操作,在高并发情况下,会引起线程频繁切换;而CAS是一种乐观锁机制,compare and swap,不加锁,而是假设没有冲突去完成,若有冲突会重试(非阻塞)。compare&swap是原子操作,基于CPU的原语操作。
       CAS仍然存在三大问题:ABA问题,循环时间长开销大,以及只能保证一个共享变量的原子操作
(2)、Volatile(变量的可见性)
       VM阻止volatile变量的值放入处理器的寄存器,在写入值以后会被从处理器的cache中flush掉,写到内存中去,这样其他线程都可以立刻看到该变量的变化。
(3)、AQS,抽象队列同步器(原子性操作状态同步位、有序队列、阻塞唤醒进程)
       获取锁:首先判断当前状态是否允许获取锁,如果是就获取锁,否则就阻塞操作或者获取失败,也就是说如果是独占锁就可能阻塞,如果是共享锁就可能失败。另外如果是阻塞线程,那么线程就需要进入阻塞队列。当状态位允许获取锁时就修改状态,并且如果进了队列就从队列中移除。
       释放锁:这个过程就是修改状态位,如果有线程因为状态位阻塞的话就唤醒队列中的一个或者更多线程。

1.2、锁优化

       今天所说的锁优化,是指在阻塞式的情况下,如何让性能不要变得太差。但是再怎么优化,一般来说性能都会比无锁的情况差一点。
       锁优化的思路和方法总结一下,有以下几种:
(1)、减少锁持有时间

       减少其他线程等待的时间,只在有线程安全要求的程序上加锁

(2)、减小锁粒度

       将大对象(这个对象可能会被很多线程访问),拆成小对象,大大增加并行度,降低锁竞争。降低了锁的竞争,偏向锁,轻量级锁成功率才会提高;最典型的减小锁粒度的案例就是ConcurrentHashMap

(3)、锁分离

       最常见的锁分离就是读写锁ReadWriteLock,根据功能进行分离成读锁和写锁,这样读读不互斥,读写互斥,写写互斥,即保证了线程安全,又提高了性能;读写分离思想可以延伸,只要操作互不影响,锁就可以分离;比如LinkedBlockingQueue

(4)、锁粗化

       通常情况下,为了保证多线程间的有效并发,会要求每个线程持有锁的时间尽量短,即在使用完公共资源后,应该立即释放锁。只有这样,等待在这个锁上的其他线程才能尽早的获得资源执行任务。但是,凡事都有一个度,如果对同一个锁不停的进行请求、同步和释放,其本身也会消耗系统宝贵的资源,反而不利于性能的优化

(5)、锁消除

       锁消除是在编译器级别的事情。在即时编译器时,如果发现不可能被共享的对象,则可以消除这些对象的锁操作。
       也许你会觉得奇怪,既然有些对象不可能被多线程访问,那为什么要加锁呢?写代码时直接不加锁不就好了?
       有时,这些锁并不是程序员所写的,有的是JDK实现中就有锁的,比如Vector和StringBuffer这样的类,它们中的很多方法都是有锁的。当我们在一些不会有线程安全的情况下使用这些类的方法时,达到某些条件时,编译器会将锁消除来提高性能
       开启锁消除是在JVM参数上设置的,当然需要在server模式下:

#开启锁消除
-server -XX:+DoEscapeAnalysis -XX:+EliminateLocks

1.3、无锁操作

       与锁相比, 使用CAS操作, 由于其非阻塞性, 因此不存在死锁问题, 同时线程之间的相互影响, 也远小于锁的方式. 使用无锁的方案, 可以减少锁竞争以及线程频繁调度带来的系统开销.
       例如:生产消费者模型中, 可以使用BlockingQueue来作为内存缓冲区,但他是基于锁和阻塞实现的线程同步。如果想要在高并发场合下获取更好的性能,则可以使用基于CAS的ConcurrentLinkedQueue;同理,如果可以使用CAS方式实现整个生产消费者模型,那么也将获得可观的性能提升,如Disruptor框架.

1.4、虚拟机内的锁优化

(1)、 偏向锁

       所谓的偏向,就是偏心,即锁会偏向于当前已经占有锁的线程
       大部分情况是没有竞争的(某个同步块大多数情况都不会出现多线程同时竞争锁),所以可以通过偏向来提高性能。即在无竞争时,之前获得锁的线程再次获得锁时,会判断是否偏向锁指向我,那么该线程将不用再次获得锁,直接就可以进入同步块
       偏向锁的实施就是将对象头Mark的标记设置为偏向,并将线程ID写入对象头Mark
       当其他线程请求相同的锁时,偏向模式结束
       JVM默认启用偏向锁:-XX:+UseBiasedLocking
       在竞争激烈的场合,偏向锁会增加系统负担(每次都要加一次是否偏向的判断

(2)、轻量级锁

       Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意
       原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现的。互斥是一种会导致线程挂起,并在较短的时间内又需要重新调度回原线程的,较为消耗资源的操作。
       为了优化Java的Lock机制,从Java6开始引入了轻量级锁的概念
       轻量级锁(Lightweight Locking)本意是为了减少多线程进入互斥的几率,并不是要替代互斥。它利用了CPU原语Compare-And-Swap(CAS,汇编指令CMPXCHG),尝试在进入互斥前,进行补救;如果偏向锁失败,那么系统会进行轻量级锁的操作。它存在的目的是尽可能不用动用操作系统层面的互斥,因为那个性能会比较差。因为JVM本身就是一个应用,所以希望在应用层面上就解决线程同步问题。
       总结一下:就是轻量级锁是一种快速的锁定方法,在进入互斥之前,使用CAS操作来尝试加锁,尽量不要用操作系统层面的互斥,提高了性能
       那么当偏向锁失败时,轻量级锁的步骤:

1、将对象头的Mark指针保存到锁对象中(这里的对象指的就是锁住的对象,比如synchronized (this){},this就是这里的对象)。lock->set_displaced_header(mark);
2、将对象头设置为指向锁的指针(在线程栈空间中)。if (mark == (markOop) Atomic::cmpxchg_ptr(lock, obj()->mark_addr(),mark)) {       TEVENT (slow_enter: release stacklock) ;       return ; }
lock位于线程栈中。所以判断一个线程是否持有这把锁,只要判断这个对象头指向的空间是否在这个线程栈的地址空间当中。

       如果轻量级锁失败,表示存在竞争,升级为重量级锁(常规锁),就是操作系统层面的同步方法。在没有锁竞争的情况,轻量级锁减少传统锁使用OS互斥量产生的性能损耗。在竞争非常激烈时(轻量级锁总是失败),轻量级锁会多做很多额外操作,导致性能下降。

(3)、自旋锁

       当竞争存在时,因为轻量级锁尝试失败,之后有可能会直接升级成重量级锁动用操作系统层面的互斥。也有可能再尝试一下自旋锁。
       如果线程可以很快获得锁,那么可以不在OS层挂起线程,让线程做几个空操作(自旋),并且不停地尝试拿到这个锁(类似tryLock),当然循环的次数是有限制的,当循环次数达到以后,仍然升级成重量级锁。所以在每个线程对于锁的持有时间很少时,自旋锁能够尽量避免线程在OS层被挂起。
       JDK1.6中:-XX:+UseSpinning开启
       JDK1.7中:去掉此参数,改为内置实现
       如果同步块很长,自旋失败,会降低系统性能。如果同步块很短,自旋成功,节省线程挂起切换时间,提升系统性能

(4)、偏向锁,轻量级锁,自旋锁总结

       上述的锁不是Java语言层面的锁优化方法,是内置在JVM当中的。
       偏向锁是为了避免某个线程反复获得/释放同一把锁时的性能消耗,如果仍然是同个线程去获得这个锁,尝试偏向锁时会直接进入同步块,不需要再次获得锁。
       轻量级锁和自旋锁是为了避免直接调用操作系统层面的互斥操作,因为挂起线程是一个很耗资源的操作。
       为了尽量避免使用重量级锁(操作系统层面的互斥),首先会尝试轻量级锁,轻量级锁会尝试使用CAS操作来获得锁,如果轻量级锁获得失败,说明存在竞争。但是也许很快就能获得锁,就会尝试自旋锁,将线程做几个空循环,每次循环时都不断尝试获得锁。如果自旋锁也失败,那么只能升级成重量级锁。偏向锁,轻量级锁,自旋锁都是乐观锁。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

他与她,一个两年前的故事

“ 有没有那个Ta,值得你一生去守护”1她能力出众,业务能力无人能出其左右;他资质平庸,扮演一个很不起眼的角色;她国色天香,是整个公司上上下下关注的焦点;他其貌不扬,甚至很多人根本…

科普 | 知识图谱相关的名词解释

知识图谱(Knowledge Graph)是谷歌于2012年提出。企业通常出于商业目的去设计新的概念和名词。但每一个概念的提出都有其历史渊源和本质内涵。下面列举了知识图谱相关的几个概念,并简要阐明了它们与知识图谱的关系和区别。Knowledge Base&…

搜索引擎核心技术与算法 —— 倒排索引初体验

今天开启一个新篇章——智能搜索与NLP。本篇章将由羸弱菜鸡小Q和大家一同学习与智能搜索相关的知识和技术,希望能和大家一同学习与进步,冲鸭!!这里首先区分两个概念:搜索和检索检索:数据库时代的概念&#…

微服务设计原则和解决方案

一、微服务架构演进过程 近年来我们大家都体会到了互联网、移动互联带来的好处,作为IT从业者,在生活中时刻感受互联网好处的同时,在工作中可能感受的却是来自自互联网的一些压力,那就是我们传统企业的IT建设也是迫切需要转型&…

技术动态 | 知识可视化,连接和探究知识之间的联系!

本文转载自公众号:东湖大数据交易中心。大数据百人会线上沙龙 第八期3月1日晚八点,大数据百人会沙龙第八期主讲嘉宾——北京知珠传媒科技有限公司CEO郝庆一先生,分享他对可视化的理解,以及连接知识、探究知识之间的关系。1可视化…

潜在语义分析原理以及python实现代码!!!!

在Wiki上看到的LSA的详细介绍,感觉挺好的,遂翻译过来,有翻译不对之处还望指教。 原文地址:http://en.wikipedia.org/wiki/Latent_semantic_analysis 前言 浅层语义分析(LSA)是一种自然语言处理中用到的方法…

史上最可爱的关系抽取指南?从一条规则到十个开源项目

正文来自订阅号:AINLP正文作者:太子長琴(NLP算法工程师)小夕,我来给你出个题,看看你的反应如何?好呀好呀,你说~“梁启超有一个著名的儿子,叫梁思成;同时还有一个著名的学…

论文浅尝 | Leveraging Knowledge Bases in LSTMs

Yang, B., Mitchell, T., 2017. Leveraging Knowledge Bases in LSTMs for Improving Machine Reading. Association for Computational Linguistics, pp. 1436–1446.链接:http://www.aclweb.org/anthology/P/P17/P17-1132.pdf这篇论文是今年发表在 ACL 的一篇文章…

支付系统-对账系统

在支付系统中,资金对账在对账中心进行,将系统保存的账务流水与银行返回的清算流水和清算文件进行对账,核对系统账务数据与银行清算数据的一致性,保证支付机构各备付金银行账户每日的预计发生额与实际发生额一致。 一、清算对账系…

在线GPU分布式实验环境+企业级项目,轻松斩获offer

人工智能微专业招生简章(春季)重构专业核心培养复合型人才与斯坦福、伯克利、MIT、清华Top10名校同学成为校友一对一学习与职业规划扫码立刻加入本季招生名额仅剩200人

支付系统-系统架构

本文主要是从支付架构、支付流程分析、支付核心逻辑、支付基础服务、支付安全五个方面来详细讲述支付系统架构 (1)、架构的定义:架构一定是基于业务功能来展开的,主要是制定技术规范、框架,指导系统落地;好…

领域应用 | 智能导购?你只看到了阿里知识图谱冰山一角

在刚刚结束的2017第四届世界互联网大会上,评选出了年度18项代表性的领先科技成果,阿里云ET大脑就是其中之一。众所周知,融合了先进的大数据、人工智能技术的阿里云ET大脑已经在智慧城市、智慧交通等众多领域得到了应用和推广。但你知不知道&a…

美团技术团队-大众点评搜索基于知识图谱的深度学习排序实践

美团技术团队博客网址:https://tech.meituan.com/2019/02/28/root-clause-analysis.html 1. 引言挑战与思路搜索是大众点评App上用户进行信息查找的最大入口,是连接用户和信息的重要纽带。而用户搜索的方式和场景非常多样,并且由于对接业务种…

NLP、炼丹技巧和基础理论文章索引

玩家你好 恭喜你捡到了一个来自上古时期的*七*星*炼*丹*炉*,只见炉壁上镶嵌着自然语言处理、推荐系统、信息检索、深度炼丹、机器学习、数学与基础算法等失传已久的江湖秘术。熔炉中虽然已有一层厚厚尘土,却依然掩盖不住尘埃下那一颗颗躁动不安的仙丹。 …

支付系统-概念与架构

一、什么是支付系统 自古以来,所有的商业活动都会产生货币的收款与付款行为。在人类漫长的历史长河中,记录收付款行为的方式不断迭代:古代的账房先生通过手工记账,工业社会通过收银机机械记账…… 今天,进入了互…

论文浅尝 | Reinforcement Learning for Relation Classification

论文链接:http://aihuang.org/p/papers/AAAI2018Denoising.pdf来源:AAAI 2018MotivationDistant Supervision 是一种常用的生成关系分类训练样本的方法,它通过将知识库与非结构化文本对齐来自动构建大量训练样本,减少模型对人工标…

2019年终总结与新年重磅福利

一只小狐狸带你解锁NLP/ML/DL秘籍圣诞已过,元旦即临回首2019,我们收获满满展望2020,我们砥砺前行在这新春佳节之际小夕给大家送上七福大礼包别怕太沉,赶紧收下吧~~~自然语言处理花生仁????神经网络与炼丹鲜虾丸????机器学…

支付系统-会计核心

一、复式记账 第一个问题:如何理解账务系统单边记账,会计系统复式记账? 有些公司内部账户之间转账都采用复式记账法,如充值、提现交易,他们在账务系统都记单边流水,等和银行对账后,在会计系统复…

领域应用 | 中医临床知识图谱的构建与应用

本文转载自公众号:e医疗。 知识图谱是近年来知识管理和知识服务领域中出现的一项新兴技术,它为中医临床知识的关联、整合与分析提供了理想的技术手段。我们基于中医医案等临床知识源,初步建立了由疾病、证候、症状、方剂、中药等核心概念所构…