CAS

Mysql悲观锁乐观锁区别与使用场景

醉酒当歌 提交于 2020-08-13 17:57:00
概念上区别 乐观锁(Optimistic Locking):顾名思义,对加锁持有一种乐观的态度,即先进行业务操作,不到最后一步不进行加锁,"乐观"的认为加锁一定会成功的,在最后一步更新数据的时候再进行加锁。 悲观锁(Pessimistic Lock):正如其名字一样,悲观锁对数据加锁持有一种悲观的态度。因此,在整个数据处理过程中,将数据处于锁定状态。悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层提供的锁机制才能真正保证数据访问的排他性,否则,即使在本系统中实现了加锁机制,也无法保证外部系统不会修改数据)。 实现方式: 乐观锁: * version方式:一般是在数据表中加上一个数据版本号version字段,表示数据被修改的次数,当数据被修改时,version值会加一。当线程A要更新数据值时,在读取数据的同时也会读取version值,在提交更新时,若刚才读取到的version值为当前数据库中的version值相等时才更新,否则重试更新操作,直到更新成功。 sql实现代码: update table set x = x + 1 , version = version + 1 where id =# { id } and version =# { version } ; CAS(定义见后)操作方式:即compare and swap 或者 compare and set

java并发编程艺术——基础篇

点点圈 提交于 2020-08-13 15:46:57
这篇文章目的是为了总结一下这段时间看《java并发编程艺术》学到的东西,尝试用自己的话说出来对java多线程的理解和使用。 一、什么是多线程,为什么要用多线程,多线程带来的挑战 多线程定义 : 多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multithreading)处理器。在一个程序中,这些独立运行的程序片段叫作“线程”(Thread),利用它编程的概念就叫作“多线程处理(Multithreading)”。–来自百度词条 为什么要使用多线程 :总的来说是因为现代计算机硬件的发展导致的,单核cpu性能的瓶颈已经难以突破,那么就在一台计算机上多加cpu呗,现在的个人电脑2核4核 的cpu已经是很普及了,更别说用作服务器的计算机了,所以近年来多线程发展如日中天。 使用多线程带来性能上的提升,什么是性能,我的理解就是同样的时间做的事情多少,比如一个小时的时间学霸可以背60个单词,我就只能记住10个单词,但是如果我能在早上做早餐的时候,比如烧水的时候,我需要 等待 水烧开

并发编程AQS----共享锁

百般思念 提交于 2020-08-13 14:41:58
Semaphore Semaphore 字面意思是信号量的意思,它的作用是控制访问特定资源的线程数目。应用场景:资源访问,服务限流。 Semaphore 实现AbstractQueuedSynchronizer的方法与 ReentrantLock 一样 Semaphore构造方法 public Semaphore( int permits) {------permits 表示能同时有多少个线程访问我们的资源 sync = new NonfairSync(permits); -------------默认创建的是非公平锁。 } abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 1192457210091910933L; Sync(int permits) { setState(permits);-------传入的permits做i为了state的值,作为资源总数 } semaphore.acquire();获取资源,源码实现 public void acquire() throws InterruptedException { sync.acquireSharedInterruptibly( 1 );--------

AQS

…衆ロ難τιáo~ 提交于 2020-08-13 13:29:03
1.是什么? AQS是构建锁和同步器的框架,主要支持获取锁和释放锁,像ReentraintLock的底层就是基于AQS实现的。获取锁时如果是独占锁就会堵塞,阻塞了就会将该线程加入阻塞队列中等待,直到成功获得锁从队列中移除。释放锁时需要修改并唤醒其他被阻塞的线程。 2.原理 1.核心组成:加锁状态state,加锁线程exclusiveOwnerThread,和阻塞队列。 阻塞队列是采用CLH模型构成的先进先出的双向队列。(CLH指虚拟的双向队列,队列只存储节点之间的关联关系,不存储节点实例) 2.获取锁的过程: 线程首先 CAS尝试 改变state状态,如果成功由0变为1表示获取成功,将exclusiveOwnerThread设为当前线程名。 如果是可重入锁,那么可以再去获得这把锁,state会累加。 另一个线程也CAS改变state,失败了就去阻塞队列里。 3.释放锁: 将state递减直至为0则释放成功,将exclusiveOwnerThread设为null同时唤醒队列中的线程。 3.其他应用 可重入锁:Reentrantlock、ReentrantReadWriteLock 不可重入锁:Mutrx 同步器:Semaphore/countDownlatch/CyclicBarrier. 来源: oschina 链接: https://my.oschina.net/u

Java是如何实现Future模式的?万字详解!

对着背影说爱祢 提交于 2020-08-13 07:21:53
JDK1.8源码分析项目(中文注释)Github地址: https://github.com/yuanmabiji/jdk1.8-sourcecode-blogs 1 Future是什么? 先举个例子,我们平时网购买东西,下单后会生成一个订单号,然后商家会根据这个订单号发货,发货后又有一个快递单号,然后快递公司就会根据这个快递单号将网购东西快递给我们。在这一过程中,这一系列的单号都是我们收货的重要凭证。 因此,JDK的Future就类似于我们网购买东西的单号,当我们执行某一耗时的任务时,我们可以另起一个线程异步去执行这个耗时的任务,同时我们可以干点其他事情。当事情干完后我们再根据future这个"单号"去提取耗时任务的执行结果即可。因此Future也是多线程中的一种应用模式。 扩展 : 说起多线程,那么Future又与Thread有什么区别呢?最重要的区别就是Thread是没有返回结果的,而Future模式是有返回结果的。 2 如何使用Future 前面搞明白了什么是Future,下面我们再来举个简单的例子看看如何使用Future。 假如现在我们要打火锅,首先我们要准备两样东西:把水烧开和准备食材。因为烧开水是一个比较漫长的过程(相当于耗时的业务逻辑),因此我们可以一边烧开水(相当于另起一个线程),一边准备火锅食材(主线程),等两者都准备好了我们就可以开始打火锅了。 //

Java多线程编程基础知识汇总

穿精又带淫゛_ 提交于 2020-08-13 05:26:47
多线程简介 多任务   现代操作系统(Windows、Linux、MacOS)都可以执行多任务,多任务就是同时运行多个任务。例如在我们的计算机上,一般都同时跑着多个程序,例如浏览器,视频播放器,音乐播放器,Word办公软件等等,由于CPU执行代码都是一条一条顺序执行的,即时是单核CPU也可以同时执行多个任务,操作系统执行多个任务实际上就是轮流让多个任务交替执行。即使是多核CPU,因为通常任务的数量是远多于CPU的核数,所以任务也是交替执行的。 进程(Process)   在计算机中,我们把一个任务称为一个进程。浏览器就是一个进程,视频播放器是另外一个进程,音乐播放器也是一个进程,在某些进程内部还需要同时执行多个子任务。例如我们在使用Word时,在打字的同时需要进行拼写检查,还可以在后台进行打印,我们把子任务称为线程。 进程和线程的关系: 一个进程可以包含一个或多个线程(至少包含一个线程) 线程是操作系统调度的最小任务单位 如何调度线程完全由操作系统决定(程序自己不能决定线程何时执行,执行多长时间) 实现多任务的三种方法: 多进程模式(每个进程只有一个线程) 多线程模式(一个进程有多个线程) 多进程+多线程(复杂度最高) 多进程和多线程的对比: 创建进程比创建线程开销大(尤其是在Windows系统上) 进程间通信比线程间通信慢 多进程稳定性比多线程高(因为在多进程的情况下

Java基础之Synchronized原理

↘锁芯ラ 提交于 2020-08-13 05:00:00
思维导图svg: https://note.youdao.com/ynoteshare1/index.html?id=eb05fdceddd07759b8b82c5b9094021a&type=note 在多线程使用共享资源的时候, 我们可以使用synchronized来锁定共享资源,使得同一时刻,只有一个线程可以访问和修改它,修改完毕后,其他线程才可以使用。这种方式叫做互斥锁。 当一个共享数据被当前正在访问到线程添加了互斥锁之后,在同一时刻,其他线程只能等待,直到当前线程释放该锁。 synchronized可以添加互斥锁,并且保证被其他线程看到。 synchronized的三种应用方式 synchronized关键字最主要有以下3种应用方式,下面分别介绍 修饰实例方法,作用于当前实例加锁,进入同步代码钱要获得当前实例的锁 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码块前要获得给定对象的锁 synchronized作用于实例方法 我们设置类变量 static 为共享资源, 然后多个线程去修改。修改的含义是: 先读取,计算,再写入。那么这个过程就不是原子的,多个线程操作就会出现共享资源争抢问题。 我们在实例方法上添加synchronized,那么,同一个实例执行本方法时,抢到锁到可以执行。 public

锁优化

耗尽温柔 提交于 2020-08-13 02:39:10
1.偏向锁: 偏向于第一个访问锁的线程,同个线程可以直接获得锁继续运行下去。 如果在运行过程中只有一个线程会访问,那么就不需要进行同步操作,这时候会给这个线程加个偏向锁。 而当有另外的线程同样想获取锁时,获取失败就会将偏向锁升级为轻量级锁。 ps:在有锁竞争的情况下,偏向锁会做很多额外操作降低性能,所以只有当没什么多线程的情况下再启动偏向锁。 2.轻量级锁: 在对象头中CAS尝试保存指向线程的指针,失败了就用自旋重新尝试,如果一直失败或又有线程尝试争抢锁,锁就会升级为重量级。 ps:此时失败并不会阻塞而是自旋重新尝试。 3.重量级锁: 就是以前的同步锁,一个线程获得锁,其他线程会被阻塞直到锁被释放后唤醒。 java同步锁优化方案学习笔记(偏向锁,轻量级锁,自旋锁,重量级锁) synchronized原理分析及自旋锁、偏向锁、轻量级锁和重量级锁的概念和优化 来源: oschina 链接: https://my.oschina.net/u/4527334/blog/4309045

纯干货,从源码解析多线程与高并发,再说不会,我不再踏足IT圈

…衆ロ難τιáo~ 提交于 2020-08-12 18:05:55
没什么太多说的,多线程与高并发,面试重点,咱直接进入正题,联合底层源码,我们从源码看一下,多线程与高并发底层的知识点,这也是阿里p8+的面试官建议的学习到的级别 CAS Compare And Swap (Compare And Exchange) / 自旋 / 自旋锁 / 无锁 因为经常配合循环操作,直到完成为止,所以泛指一类操作 cas(v, a, b) ,变量v,期待值a, 修改值b ABA问题,你的女朋友在离开你的这段儿时间经历了别的人,自旋就是你空转等待,一直等到她接纳你为止 解决办法(版本号 AtomicStampedReference),基础类型简单值不需要版本号 Unsafe AtomicInteger: public final int incrementAndGet () { for (;;) { int current = get(); int next = current + 1 ; if (compareAndSet(current, next)) return next; } } public final boolean compareAndSet ( int expect, int update) { return unsafe.compareAndSwapInt( this , valueOffset, expect, update); }

操作系统—进程控制

。_饼干妹妹 提交于 2020-08-12 15:44:04
正进程控制就是要实现进程状态转换 创建态 ---> 就绪态<--->运行态--->阻塞态 运行态转为终止态 阻塞态可以转为就绪态 程序原语:一种特殊的程序,执行具有原子性,也就是说,这段程序必须一气呵成,不可中断。 如何实现进行控制呢? 原语实现。 如果中间可打断,会发生什么? 如果不能“一气呵成”,就有可能导致操作系 统中的某些关键数据结构信息不统一的情况, 这会影响操作系统进行别的管理工作 两步要保证原子性,类似于cas,比较与交换是原子性操作。 pcb进程控制bai块(duPCB,Process Control Block) 撤销原语: 从pcb集合中找到终止进程的pcb,若进程正在运行,立即剥夺cpu,将cpu的执行权分配给其他进程,终止其他子进程。进程间是树形结构,将该进程拥有的所有资源归还给父进程或者操作系统,删除pcb。 引起程序终止的事件 正常结束:进程自己请求终止 异常结束:整数除以0,被操作系统强行杀掉 外界干扰:ctrl+alt+delete用户选择杀掉进程。 阻塞原语: 找到要阻塞的进程对应的pcb,保护进程运行现场,讲pcb状态信息设置为阻塞态,将pcb插入到 相应事件的等待队列。 引起进程阻塞的事件: 需要等待系统分配某种资源 需要等待相互合作的其他进程完成工作 唤醒原语: 在事件等待队列里找打pcb,将pcb从等到队列移除,设置进程为就绪态