随笔分类 -  并发编程

摘要:总结 1、write skew 问题,是基础版多版本并发控制方案,在版本提交时,只处理了 写 - 写 冲突,而未处理存在控制依赖关系的 读 - 写 冲突。 2、对于相同数据的写入操作保证了并发安全,但当该写入操作依赖的数据,被其他事务修改的情况发生时,就会出现并发问题。 3、对于一个事务涉及的数据全 阅读全文
posted @ 2023-06-28 10:26 牛有肉 阅读(347) 评论(0) 推荐(0) 编辑
摘要:在 spring 中大部分时候使用的是声明式事务,也就是 @Transaction 注解,但在某些特殊情况下也需要手动控制事务的开启/提交/回滚。 工具类封装: 1 @Component 2 public class TransactionUtils { 3 @Resource 4 private 阅读全文
posted @ 2022-11-17 15:04 牛有肉 阅读(4263) 评论(0) 推荐(0) 编辑
摘要:Lost Update 问题 A4的访问模式r1[x], w2[x], w2[commit], w1[x], w1[commit] 这种访问模式下,w2的更新可能会丢失。因为w1可能基于一个比较old-x来做更新x的操作。 RR 隔离级别下的事务表现 快照读 测试数据: 事务 1: start tr 阅读全文
posted @ 2022-11-17 14:59 牛有肉 阅读(431) 评论(0) 推荐(0) 编辑
摘要:/** * @Author Niuxy * @Date 2020/6/10 9:42 下午 * @Description 多 selector 多线程的 NIO 服务端 * 使用 NIO 时一定要摒弃 BIO 的阻塞思维,我们的代码面向的是事件,而不是连接 * 至于多次事件完成一个连接的情况,我们可 阅读全文
posted @ 2020-06-13 13:25 牛有肉 阅读(1259) 评论(0) 推荐(0) 编辑
摘要:在多道编程的情况下,想要保证线程按我们预想的方式协作,抛开原子性、可见性、有序性的概念,白话总结下心得: 1. 从涉及到操作共享数据的指令入手,保证它们对共享数据操作的正确性。 2. 首先保证单线程情况下,程序执行的正确性。然后判断线程中,与操作共享变量的指令存在数据依赖的指令构成的指令集。保证指令 阅读全文
posted @ 2020-06-09 21:38 牛有肉 阅读(332) 评论(0) 推荐(0) 编辑
摘要:最近工作比较忙,水一篇: /** * @Author Niuxy * @Date 2020/6/8 8:54 下午 * @Description 基于双向链表的简单 FIFO 队列 * 锁的粒度很粗,仅针对最上层操作进行互斥同步关系规划 * 最上层方法有两个:put 与 remove * 以 len 阅读全文
posted @ 2020-06-09 20:09 牛有肉 阅读(260) 评论(0) 推荐(0) 编辑
摘要:众所周知,JVM 创建一个对象分三步: 1.在堆内存开辟内存空间。 2.在堆内存中实例化Car里面的各个参数。 3.把对象指向堆内存空间。 为了提高运行效率,编译器在编译代码时可能会对指令进行重排序。重排序的原则是,保证单线程执行结果的正确性,并遵循 happen-before 原则。 指令间的依赖 阅读全文
posted @ 2020-06-04 23:15 牛有肉 阅读(455) 评论(0) 推荐(0) 编辑
摘要:Reactor 模型不再介绍,网上有很多。在实现的过程中有一些收获: 1. Reactor 广义上说,事件发生时便会触发为事件注册的处理函数。在注册感兴趣的事件时,需要将处理函数一并绑定到事件上,在 NIO 中我们通过 SelectionKey 的 attachment 携带函数对象。 2. 使用 阅读全文
posted @ 2020-06-02 23:38 牛有肉 阅读(603) 评论(0) 推荐(1) 编辑
摘要:使用 JAVA 进行多道编程时,除了通过 wait/notify 对线程进行阻塞/唤醒外,我们还可以使用 LockSupport 工具类来阻塞和唤醒线程。 比如: Thread threadTest = new Thread( () -> { System.out.println("thread s 阅读全文
posted @ 2020-04-16 21:12 牛有肉 阅读(2364) 评论(0) 推荐(0) 编辑
摘要:事务的 ACID 特性是保证事务正确执行的必要因素,这四个特性不仅是数据库对事务安全的保障机制,拓展开来,也为我们在多线程编程环境下,提供了保证任务正确执行的参考。数据库事务是一类特殊的多道编程任务,之所以特殊是因为这些任务对周遭环境是存在函数副作用的,因为它们改变了任务外定义的共享资源的状态(数据 阅读全文
posted @ 2020-04-05 23:53 牛有肉 阅读(217) 评论(0) 推荐(0) 编辑
摘要:池化是我们在实际生产中经常用到的一种思想,通过一个 “池” 把资源统一的管理起来。可以达到对资源的合理管理、重复利用、减少资源创建/销毁的开销等目的。 常见的比如常量池、连接池、线程池,今天我们手撸一个线程池。 抛开语言特性,线程池无非是维护一堆线程阻塞等待任务的到来,并由主线程对任务线程的数量进行 阅读全文
posted @ 2020-03-14 23:33 牛有肉 阅读(3657) 评论(0) 推荐(0) 编辑
摘要:kill 掉一个线程,感觉是一件很简单的事情,比如 JAVA 中为我们提供了 stop 方法可以立即终止线程的执行,达到 kill 掉线程的目的。 但实际上对线程的操作是一件精细活,对于一段正在执行的任务,我们不能只是简单粗暴的勒令其停止。原因就是,线程与资源是有关联的。 比如,一个线程持有某个 l 阅读全文
posted @ 2020-03-09 21:57 牛有肉 阅读(4020) 评论(0) 推荐(0) 编辑
摘要:看题目: 第一种解法采用绝对悲观锁保证绝对的线程安全,思路很简单:不考虑线程协作写代码,然后找出单线程环境下存在控制依赖与数据依赖且涉及共享变量的部分,保证其原子性后确定互斥关系,决定那些操作是互斥的,则共用一把锁。 class H2O { int hNums=0; int oNums=0; pub 阅读全文
posted @ 2020-03-09 00:04 牛有肉 阅读(350) 评论(0) 推荐(0) 编辑
摘要:首先认识一下 CAS:CAS是支持并发的第一个处理器提供原子的测试并设置操作,通常在单位上运行这项操作。操作数为V,A,B。 CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。否则,处理器不做任何操作 阅读全文
posted @ 2020-03-08 22:13 牛有肉 阅读(950) 评论(0) 推荐(0) 编辑
摘要:先吐槽一下网上对原子性的解释,总是说原子性是不可分割的。 那只是在单核心下的语义,单核心下不可分割的操作意味着执行过程中不会有其它线程执行,从而导致变量污染,也就是原子性操作涉及的共享变量是安全的。 所以多线程下原子性的语义也应该是 :原子性操作涉及的共享变量是安全的,不会有其它线程修改。 也就是说 阅读全文
posted @ 2020-03-08 01:00 牛有肉 阅读(398) 评论(0) 推荐(0) 编辑
摘要:总结: 1. 如果在单线程环境下,几个操作共享变量的方法存在数据依赖关系,那么多线程环境下它们必须是一组原子操作,且与任何修改共享变量的方法互斥。与读方法是否互斥需要看程序的设计,比如 CopyOnWrite 模式下,这些原子操作不会与读共享变量的动作互斥,可以提高读的效率,但缺点是不能保证读操作每 阅读全文
posted @ 2020-03-05 19:48 牛有肉 阅读(349) 评论(0) 推荐(0) 编辑
摘要:写过 JAVA 并发代码的同学对 synchronized 关键字一定是熟的不能再熟了,其基于对象头部的 monitor 实现了对代码块的加锁,使一段代码变为线程不可重入的。 synchronized 与操作系统层的 lock 与 unlock 机制非常类似,多线程通过一个共享变量通信,这个共享变量 阅读全文
posted @ 2020-03-04 01:03 牛有肉 阅读(173) 评论(0) 推荐(0) 编辑
摘要:happen-before 可真是一个经典又老生常谈的话题,规则一共就八条,但看起来总有种抓不住重点的感觉。今天再整理一下对这八条规则的理解。 首先我的理解是 happen-before 的语义与在什么什么之前发生完全没有关系,其语义是如果 A hapen-bfore B,那么 A 的结果对 B 是 阅读全文
posted @ 2020-03-02 21:45 牛有肉 阅读(7149) 评论(2) 推荐(2) 编辑
摘要:数据一致性部分借用大神“耗叔”的博客:https://coolshell.cn/articles/20793.html。 总结:volatile 关键字通过内存屏障禁止了指令的重排序,并在单个核心中,强制数据的更新及时更新到缓存。在此基础上,依靠多核心处理器的缓存一致性协议等机制,保证了变量的可见性 阅读全文
posted @ 2020-03-02 19:00 牛有肉 阅读(3520) 评论(2) 推荐(2) 编辑
摘要:CPU 在运行时为了响应外部的请求,对外提供了一个中断引脚。CPU 在每个指令周期的最后一个晶振周期检查中断引脚,如果有中断任务,则立即停止手中的工作(当然要先保存现场)调用相应中断号的中断处理程序对中断做出响应。 进程在运行时为了响应外部请求,对外提供了信号队列。在每次由核心态转为用户态(比如由进 阅读全文
posted @ 2020-03-01 23:18 牛有肉 阅读(1037) 评论(0) 推荐(0) 编辑