CAS

深入理解CAS算法原理

时光怂恿深爱的人放手 提交于 2020-02-26 10:14:59
1、什么是CAS? CAS:Compare and Swap,即比较再交换。 jdk5增加了并发包java.util.concurrent.*,其下面的类使用CAS算法实现了区别于synchronouse同步锁的一种乐观锁。JDK 5之前Java语言是靠synchronized关键字保证同步的,这是一种独占锁,也是是悲观锁。 2、CAS算法理解 对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。 CAS比较与交换的伪代码可以表示为: do{ 备份旧数据; 基于旧数据构造新数据; }while(!CAS( 内存地址,备份的旧数据,新数据 )) https://upload-images.jianshu.io/upload_images/5954965-b88918b03518f254?imageMogr2/auto-orient/strip|imageView2/2/w/320/format/webp 注:t1,t2线程是同时更新同一变量56的值 因为t1和t2线程都同时去访问同一变量56,所以他们会把主内存的值完全拷贝一份到自己的工作内存空间,所以t1和t2线程的预期值都为56。 假设t1在与t2线程竞争中线程t1能去更新变量的值,而其他线程都失败。

总结:Java锁机制

那年仲夏 提交于 2020-02-26 09:59:57
一、 synchronized 原生关键字 二、 Lock lock()方法:获取锁,被占用则等待,直到等到为止,即阻塞式获取; lock.lockInterruptibly()方法:类似lock(),唯一不同的是,这个获取(阻塞)过程可以代码去中断的,即假设B线程在等待A线程的锁,B线程可以通过调用interrupt()方法中断自己的等待。 注意:只能中断阻塞线程,不会中断执行中的线程 。 更确切 的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞, 那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。 tryLock():非阻塞式获取,即获取不到不会等待,立即返回失败 tryLock(long time, TimeUnit unit):非阻塞式获取,即获取不到,则会等待unit时间,如果还未获取到,则返回失败。 newCondition(): 返回一个绑定到lock对象上的condition对象,作用是处理一些条件下的问题,如边界问题(如数组满则不能put,数组空则不能take等) ReentrantLock ,即 可重入锁。ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。 参考:

redis, memcache性能比较

ぐ巨炮叔叔 提交于 2020-02-26 09:59:41
1、性能 都比较高 总体来讲,TPS方面redis和memcache差不多 2、操作的便利性 memcache数据结构单一; redis丰富一些,数据操作方面,redis更好一些,较少的网络IO次数 3、内存空间的大小和数据量的大小 redis在2.0版本后增加了自己的VM特性,突破物理内存的限制;可以对key value设置过期时间(类似memcache) memcache可以修改最大可用内存,采用LRU( 最近最久未使用 )算法 4、可用性(单点问题) 对于单点问题, redis,依赖客户端来实现分布式读写;主从复制时,每次从节点重新连接主节点都要依赖整个快照,无增量复制,因性能和效率问题, 所以单点问题比较复杂;不支持自动sharding,需要依赖程序设定一致hash 机制。 一种替代方案是,不用redis本身的复制机制,采用自己做主动复制(多份存储),或者改成增量复制的方式(需要自己实现),一致性问题和性能的权衡 Memcache本身没有数据冗余机制,也没必要;对于故障预防,采用依赖成熟的hash或者环状的算法,解决单点故障引起的抖动问题。 5、可靠性(持久化) 对于数据持久化和数据恢复, redis支持(快照、AOF):依赖快照进行持久化,aof增强了可靠性的同时,对性能有所影响; memcache不支持,通常用在做缓存,提升性能; 6、数据一致性(事务支持)

【笔记】并发

拜拜、爱过 提交于 2020-02-26 07:39:48
一篇文章带你解析,乐观锁与悲观锁的优缺点 乐观锁与悲观锁 乐观锁与悲观锁不是指具体的什么类型的锁,而是指看待并发同步的角度。 定义 适用场景 使用 优缺点 悲观锁 悲观的认为,不加锁的并发操作一定会出问题。 写操作非常多 就是利用各种锁(synchronized独占锁) 保证数据安全 使用synchronized同步锁进行线程阻塞和唤醒切换以及用户态内核态间的切换操作额外浪费消耗cpu资源 乐观锁 认为对于同一个数据的并发操作,是不会发生修改的。 读操作非常多 无锁编程,采用的是CAS算法,典型的例子就是原子类,通过CAS自旋实现原子操作的更新。 不加锁会带来大量的性能提升。 冲突多时,自旋消耗大 在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延时,引起性能问题。 (2)一个线程持有锁会导致其它所有需要此锁的线程挂起。 (3)如果一个优先级高的线程等待一个优先级低的线程释放锁会导致优先级倒置,引起性能风险。 CAS 定义 CAS,compare and swap的缩写,比较并交换。 CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。有效地说明了“我认为位置 V 应该包含值 A;如果包含该值,则将 B 放到这个位置;否则,不要更改该位置,只告诉我这个位置现在的值即可。 存在的问题 ABA问题。 但是如果一个值原来是A,变成了B,又变成了A

40个Java多线程问题总结

爷,独闯天下 提交于 2020-02-26 07:39:29
前言 这些多线程的问题,有些来源于各大网站、有些来源于自己的思考。可能有些问题网上有、可能有些问题对应的答案也有、也可能有些各位网友也都看过,但是本文写作的重心就是所有的问题都会按照自己的理解回答一遍,不会去看网上的答案,因此可能有些问题讲的不对,能指正的希望大家不吝指教。 1、多线程有什么用? (1)发挥多核CPU的优势 随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4核、8核甚至16核的也都不少见,如果是单线程的程序,那么在双核CPU上就浪费了50%,在4核CPU上就浪费了75%。单核CPU上所谓的"多线程"那是假的多线程,同一时间处理器只会处理一段逻辑,只不过线程之间切换得比较快,看着像多个线程"同时"运行罢了。多核CPU上的多线程才是真正的多线程,它能让你的多段逻辑同时工作,多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的。 (2)防止阻塞 从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题

0207 软件是如何运行和崩溃的?

徘徊边缘 提交于 2020-02-26 07:01:22
背景 程序员的任务是写代码【软件】,代码【软件】本身无价值,代码【软件】运行起来才能实现价值。 运行 以java程序为例: 首先把代码通过编译器编译成可执行代码。 运行过程:冯洛伊曼模型 操作系统从磁盘中加载 程序(代码)到内存,程序变成了进程; 操作系统调度cpu给到进程,完成计算任务; 操作系统协调io设备,输出计算结果; 内存模型: 程序代码 程序代码中的数据结构; 数组需要分配内存到堆上; 数据结构对应的内存地址分配到栈上; 程序执行过程:基于栈帧 进程的状态: 运行(获得cpu,正在执行计算) 就绪(差cpu资源) 堵塞(获得cpu也无法完成计算) 因为进程的切换代价太大,操作系统引入了线程。 一台计算机如何运行多个计算任务?<br />基于cpu的共享分时技术(时间片轮转) + 多线程 ; 崩溃 以一个简单的tomcat+javaweb程序为例: 首先看运行模型: 当多个线程需要修改共享数据的时候,为了保证数据的一致性,引入了操作系统的锁; 一个请求对应一个线程,如果请求数不断增加,就会有很多的线程因为锁而进入等待状态,导致程序响应变慢; 当等待线程超过系统的极限,程序会崩溃; 如何解决并发问题引起的系统变慢和崩溃?<br />使用分布式集群的方式替代单台服务器,资源多了,等待的线程就变少了;<br />此外,限流是为了控制等待线程数量超过系统极限而程序崩溃;<br /

心跳与超时:高并发高性能的时间轮超时器

♀尐吖头ヾ 提交于 2020-02-26 05:21:08
心跳与超时:高并发高性能的时间轮超时器 [TOC] 引言 在许多业务场景中,我们都会碰到延迟任务,定时任务这种需求。特别的,在网络连接的场景中,常常会出现一些超时控制。由于服务端的连接数量很大,这些超时任务的数量往往也是很庞大的。实现对大量任务的超时管理并不是一个容易的事情。 本章我们将介绍几种用于实现超时任务的数据结构,并且最后分析 Netty 在超时任务上采取的结构和代码。 欢迎加入技术交流群186233599讨论交流,也欢迎关注笔者公众号:风火说。 JDK 原生提供的超时任务支持 java.util.Timer JDK 在 1.3 的时候引入了 Timer 数据结构用于实现定时任务。 Timer 的实现思路比较简单,其内部有两个主要属性: TaskQueue :定时任务抽象类 TimeTask 的列表。 TimerThread :用于执行定时任务的线程。 Timer 结构还定义了一个抽象类 TimerTask 并且继承了 Runnable 接口。业务系统实现了这个抽象类的 run 方法用于提供具体的延时任务逻辑。 TaskQueue 内部采用大顶堆的方式,依据任务的触发时间进行排序。而 TimerThread 则以死循环的方式从 TaskQueue 获取队列头,等待队列头的任务的超时时间到达后触发该任务,并且将任务从队列中移除。 Timer 的数据结构和算法都很容易理解

阿里巴巴大佬和你聊聊Java的几把JVM级锁

不打扰是莪最后的温柔 提交于 2020-02-26 03:29:28
简介 在计算机行业有一个定律叫"摩尔定律",在此定律下,计算机的性能突飞猛进,而且价格也随之越来越便宜, CPU 从单核到了多核,缓存性能也得到了很大提升,尤其是多核 CPU 技术的到来,计算机同一时刻可以处理多个任务。在硬件层面的发展带来的效率极大提升中,软件层面的多线程编程已经成为必然趋势,然而多线程编程就会引入数据安全性问题,有矛必有盾,于是发明了“锁”来解决线程安全问题。在这篇文章中,总结了 Java 中几把经典的 JVM 级别的锁。 synchronized synchronized 关键字是一把经典的锁,也是我们平时用得最多的。在 JDK1.6 之前, syncronized 是一把重量级的锁,不过随着 JDK 的升级,也在对它进行不断的优化,如今它变得不那么重了,甚至在某些场景下,它的性能反而优于轻量级锁。在加了 syncronized 关键字的方法、代码块中,一次只允许一个线程进入特定代码段,从而避免多线程同时修改同一数据。 synchronized 锁有如下几个特点: 有锁升级过程 在 JDK1.5 (含)之前, synchronized 的底层实现是重量级的,所以之前一致称呼它为"重量级锁",在 JDK1.5 之后,对 synchronized 进行了各种优化,它变得不那么重了,实现原理就是锁升级的过程。我们先聊聊 1.5 之后的 synchronized

一文带你精通CAS,由浅入深,直击灵魂

二次信任 提交于 2020-02-26 02:32:32
推荐阅读: 阿里二面凉经:虚拟机+MySQL+中间件+设计模式+缓存+Spring+并发等难题,全部迎刃而解 后端开发中大家肯定遇到过实现一个线程安全的计数器这种需求,根据经验你应该知道我们要在多线程中实现 共享变量 的原子性和可见性问题,于是锁成为一个不可避免的话题,今天我们讨论的是与之对应的无锁 CAS。本文会从怎么来的、是什么、怎么用、原理分析、遇到的问题等不同的角度带你真正搞懂 CAS。 为什么要无锁 我们一想到在多线程下保证安全的方式头一个要拎出来的肯定是锁,不管从硬件、操作系统层面都或多或少在使用锁。锁有什么缺点吗?当然有了,不然 JDK 里为什么出现那么多各式各样的锁,就是因为每一种锁都有其优劣势。 使用锁就需要获得锁、释放锁,CPU 需要通过上下文切换和调度管理来进行这个操作,对于一个 独占锁 而言一个线程在持有锁后没执行结束其他的哥们就必须在外面等着,等到前面的哥们执行完毕 CPU 大哥就会把锁拿出来其他的线程来抢了(非公平)。锁的这种概念基于一种悲观机制,它总是认为数据会被修改,所以你在操作一部分代码块之前先加一把锁,操作完毕后再释放,这样就安全了。其实在 JDK1.5 使用 synchronized 就可以做到。 但是像上面的操作在多线程下会让 CPU 不断的切换,非常消耗资源,我们知道可以使用具体的某一类锁来避免部分问题。那除了锁的方式还有其他的吗?当然

高并发软件层面解决思路-从前端到后端

我的梦境 提交于 2020-02-26 00:52:32
1、页面缓存、前后端分离、CDN、静态页面(减少后台接口请求,需要CMS系统支持)、代码等优化(百度关键词“雅虎前端优化”) 2、nginx或其它配置合理的负载均衡策略,按主机性能设置合理的权重等 3、应用拆分、扩容(新增实例) 4、SQL优化、JVM调优、代码逻辑优化(使用高性能API、合理使用事务及设置合理隔离级别、使用细粒度锁或无锁CAS、使用高性能并发容器如atomic、concurrentHashMap,减少日志输出多问一下自己,这个日志真的有用吗,真的有人看吗等尽可能减少系统的性能消耗)) 5、使用Redis等缓存、使用搜索引擎 6、使用MQ异步处理实时性、一致性要求不高的业务 7、限流、熔断 8、表结构优化、读写分离(读主写从,写库去除不必要的索引)、分表分库 来源: oschina 链接: https://my.oschina.net/u/4167465/blog/3167752