原子操作

Volatile详解

匿名 (未验证) 提交于 2019-12-03 00:21:02
之前研究了一下内存模型,java内存模型中很关键的一点就是Volatile,现在跟大家探讨一下Volatile的知识吧 1.volatile关键字的两层语义   一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:   1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。   2)禁止进行指令重排序。   先看一段代码,假如线程1先执行,线程2后执行: 这段代码是很典型的一段代码,很多人在中断线程时可能都会采用这种标记办法。但是事实上,这段代码会完全运行正确么?即一定会将线程中断么?不一定,也许在大多数时候,这个代码能够把线程中断,但是也有可能会导致无法中断线程(虽然这个可能性很小,但是只要一旦发生这种情况就会造成死循环了)。   下面解释一下这段代码为何有可能导致无法中断线程。在前面已经解释过,每个线程在运行过程中都有自己的工作内存,那么线程1在运行的时候,会将stop变量的值拷贝一份放在自己的工作内存当中。   那么当线程2更改了stop变量的值之后,但是还没来得及写入主存当中,线程2转去做其他事情了,那么线程1由于不知道线程2对stop变量的更改,因此还会一直循环下去。   但是用volatile修饰之后就变得不一样了:   第一

图像超分辨

匿名 (未验证) 提交于 2019-12-03 00:21:02
原博客地址: https://blog.csdn.net/u011630458/article/details/65635155   这段时间在看基于字典的单帧图像超分辨率重建,本篇主要是对这块做个笔记记录。 1 、准备好用于字典训练的低分辨率图像 LR 及与之对应的高分辨率图片 HR 。 2 、将低分辨率图像双线性或者三次方插值到高分辨率图像相同大小,得到 MR 。 3 、将 MR 图像分成若干个 3x3 或者 5x5 之类的小块,小块之间有 1x1 或者 2x2 之类的重叠区域,对应的高分辨率图像同样对应坐标位置,分成这个多块。 4 、对 MR 的图像块做特征提取操作,可以是每个块减去该块平均值、或者是每个块做梯度散度提取。 1 、 MR 特征块集合作为低分辨率字典,对应的高分辨率块集合作为高分辨率字典。 2 、输入待处理的低分辨率图像,并用和字典训练一样的块大小做分割。 3 、所有低分辨率图像分割块做特征提取。 4 、每个特征块 X ,在低分辨率字典中找到最接近的 K 个块。 5 、通过这 K 个块,拟合得到最接近该特征块的权重系数 A 。 6 、找到高分辨率字典上对应的该 K 个块,乘上权重系数 A ,得到低分辨率块 X 对应的高分辨率图像块 Y 。 7 、循环计算,直到所有低分辨率块都得到对应高分辨率块。 8 、所有高分辨率块,根据之前分割坐标,反向贴合

解决原子性问题?脑海中有这个模型就可以了

匿名 (未验证) 提交于 2019-12-03 00:11:01
上一篇文章 可见性有序性,Happens-before来搞定 ,解决了并发三大问题中的两个,今天我们就聊聊如何解决原子性问题 原子性问题的源头就是 线程切换 ,但在多核 CPU 的大背景下,不允许线程切换是不可能的,正所谓「魔高一尺,道高一丈」,新规矩来了: 互斥: 同一时刻只有一个线程执行 实际上,上面这句话的意思是: 对共享变量的修改是互斥的,也就是说线程 A 修改共享变量时其他线程不能修改,这就不存在操作被打断的问题了,那么如何实现互斥呢? 对并发有所了解的小伙伴马上就能想到 锁 这个概念,并且你的第一反应很可能就是使用 synchronized,这里列出来你常见的 synchronized 的三种用法: public class ThreeSync { private static final Object object = new Object (); public synchronized void normalSyncMethod (){ //临界区 } public static synchronized void staticSyncMethod (){ //临界区 } public void syncBlockMethod (){ synchronized ( object ){ //临界区 } } } 三种 synchronized 锁的内容有一些差别:

【c++】atomic原子操作基本用法,模板函数。

匿名 (未验证) 提交于 2019-12-03 00:02:01
【转载】: https://owent.net/2012/611.html 主要的函数如下: 函数名 | 描述 | ―――――|――――-| atomic_store | 保存非原子数据到原子数据结构 | atomic_load | 读取原子结构中的数据 | atomic_exchange | 保存非原子数据到原子数据结构,返回原来保存的数据 | atomic_fetch_add | 对原子结构中的数据做加操作 | atomic_fetch_sub/atomic_fetch_sub_explicit | 对原子结构中的数据做减操作 | atomic_fetch_and | 对原子结构中的数据逻辑与 | atomic_fetch_or | 对原子结构中的数据逻辑或 | atomic_fetch_xor | 对原子结构中的数据逻辑异或 刚才提到了在原子操作时候的内存操作规则,内存操作规则主要是 std::memory_order,这是个枚举类型,里面包含着N多规则 ֵ | 定义规则 | memory_order_relaxed | 不保证顺序 | memory_order_consume | 类比生产者-消费者模型中的消费者读取动作(仅是读取,无计数器),保证该操作先于依赖于当前读取的数据(比如后面用到了这次读取的数据)不会被提前,但不保证其他读取操 作的顺序

并发编程的三大特性

匿名 (未验证) 提交于 2019-12-02 23:35:02
线程安全性 如果一个类在单线程环境下能运行正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能运行正常,那么这个类具有线程安全性。 竞态的模式:read-modify-write(读-改-写)和check-then-act(检测而后行动)。 原子性 原子性:访问(读、写)某个共享变量的操作从其执行线程以外的任何线程来看,该操作要么已经执行结束要么尚未发生,即其他线程不会看到该操作执行了部分的中间效果。 假定有两个操作A和B,如果从执行A的线程来看,当另一个线程执行B时,要么将B全部执行完,要么完全不执行B,那么A和B对彼此来说是原子的。 public class AtomicityDemo { /** * person初始name = 李四,age = 30 * 线程1将person更新为name = 张三,age = 20,线程2得到person * 1、线程1执行updatePerson方法的person.setName(name); name = 张三 * 2、线程2执行getPerson方法的person.getName();name = 张三 * 3、线程2执行getPerson方法的person.getAge();age = 30 * 4、线程1执行updatePerson方法的person.setAge(age); age = 20 *

[正点原子]STM32开发板F103 第41讲 RTC实时时钟备份区域BKP原理 QQ860099671

匿名 (未验证) 提交于 2019-12-02 23:34:01
RTC模块与 时钟配置系统在后备区域,在复位时候不会被清除(框图: 中文参考手册) 如何使用RTC实现时钟?RTCCLK RTC_PRL是自动重装载寄存器 假如RTCCLK=100hz,那么 RTCCLK/RTC_PRL=100/100=1HZ=TR_CLK RTC_DIV就是从100往下减, 那么需要RTCCLK的一百个周期,RTC_DIV(向下计数器)就会溢出,那么就是每一个RTCCLK周期RTC_DIV就减一。 RTC_DIV 比TR_CLK更精确 ,那么,由以上公式可知,TR_CLK就是1hz也就是1s。 每一个TR_CLK就会加一,一直到overflow(溢出)就会产生中断, 还有一个秒中断 RTC_Second,(一秒钟产生一次中断) BKP备份寄存器的访问, RTC相关寄存器 RTC 相关的寄存器定义在stm32f10x.h里面有一个结构体。 寄存器的介绍在《中文参考手册》 RTCOFF 在对RTC寄存器进行写操作之前必须先判断上一次写操作已经结束,也就是判断上一次写操作是否置位。 RTC_PRLH 与RTC_PRLL 就是预分频装载寄存器的高位和低位 表示当前时间的寄存器,通常会配置为1秒钟加一 以上为闹钟寄存器,也是两个16位的,一共32位,它与计数器寄存器基本上是一样的,因为他要与计数器寄存器相比较相等就会产生中断。 2设置CNF位为1,进入配置模式

Java并发编程:volatile关键字解析

匿名 (未验证) 提交于 2019-12-02 21:53:52
Java并发编程:volatile关键字解析    volatile这个关键字可能很多朋友都听说过,或许也都用过。在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果。在Java 5之后,volatile关键字才得以重获生机。   volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情。由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理,最后给出了几个使用volatile关键字的场景。   以下是本文的目录大纲:   一.内存模型的相关概念   二.并发编程中的三个概念   三.Java内存模型   四..深入剖析volatile关键字   五.使用volatile关键字的场景   若有不正之处请多多谅解,并欢迎批评指正。   请尊重作者劳动成果,转载请标明原文链接:    http://www.cnblogs.com/dolphin0520/p/3920373.html 一.内存模型的相关概念   大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入。由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存在一个问题

Java原子类实现原理分析

匿名 (未验证) 提交于 2019-12-02 21:53:52
并发包中的原子类可以解决类似num++这样的复合类操作的原子性问题,相比锁机制,使用原子类更精巧轻量,性能开销更小,下面就一起来分析下原子类的实现机理。 悲观的解决方案(阻塞同步)   我们知道,num++看似简单的一个操作,实际上是由 1.读取 2.加一 3.写入 所以我们之前提到过的volatile是无法解决num++的原子性问题的 ),在并发环境下,如果不做任何同步处理,就会有线程安全问题。最直接的处理方式就是 加锁 。 synchronized(this){ num++; }   使用独占锁机制来解决,是一种 悲观的 并发策略,抱着一副“总有刁民想害朕”的态势,每次操作数据的时候都认为别的线程会参与竞争修改,所以直接加锁。同一刻只能有一个线程持有锁,那其他线程就会阻塞。线程的挂起恢复会带来很大的性能开销,尽管jvm对于非竞争性的锁的获取和释放做了很多优化, 但是一旦有多个线程竞争锁,频繁的阻塞唤醒,还是会有很大的性能开销的 。所以,使用synchronized或其他重量级锁来处理显然不够合理。 乐观的解决方案(非阻塞同步)   乐观的解决方案,顾名思义,就是很大度乐观,每次操作数据的时候,都认为别的线程不会参与竞争修改,也不加锁。如果操作成功了那最好;如果失败了,比如中途确有别的线程进入并修改了数据(依赖于冲突检测),也不会阻塞,可以采取一些补偿机制,一般的策略就是反复重试

Java面试官最爱问的volatile关键字

匿名 (未验证) 提交于 2019-12-02 21:53:32
在Java的面试当中,面试官最爱问的就是volatile关键字相关的问题。经过多次面试之后,你是否思考过,为什么他们那么爱问volatile关键字相关的问题?而对于你,如果作为面试官,是否也会考虑采用volatile关键字作为切入点呢? 爱问volatile关键字的面试官,大多数情况下都是有一定功底的,因为volatile作为切入点,往底层走可以切入Java内存模型(JMM),往并发方向走又可接切入Java并发编程,当然,再深入追究,JVM的底层操作、字节码的操作、单例都可以牵扯出来。 所以说懂的人提问题都是有门道的。那么,先整体来看看volatile关键字都设计到哪些点:内存可见性(JMM特性)、原子性(JMM特性)、禁止指令重排、线程并发、与synchronized的区别……再往深层次挖,可能就涉及到字节码、JVM等。 不过值得庆幸的是,如果你已经学习了微信公众号“程序新视界”JVM系列的文章,上面的知识点已经不是什么问题了,权当是复习了。那么,下面就以面试官提问的形式,在不看答案的情况下,尝试回答,看看学习效果如何。夺命连环问,开始…… 被volatile修饰的共享变量,就具有了以下两点特性: 保证了不同线程对该变量操作的内存可见性; 禁止指令重排序; 回答的很好,点出了volatile关键字两大特性。针对该两大特性继续深入。 该问题涉及到Java内存模型(JVM

深入理解Atomic原子类

匿名 (未验证) 提交于 2019-12-02 21:40:25
Atomic是基于 unsafe类 和 自旋操作 实现的,下面以AtomicInteger类为例进行讲解。 要理解Atomic得先了解CAS CAS CAS全程Compare And Swap ,是条并发原语,功能是判断内存中某个值是否与预期值相等,相等就用新值更新旧值,否则不更新。 Java中CAS是基于unsafe类实现的,所有的unsafe类中的方法都是native类修饰的,直接调用操作系统底层资源执行响应的任务。 unsafe.compareAndSwapInt(this, valueOffset, expect, update); 这是一条调用unsafe类中的compareAndSwapInt的方法,this表示当前对象,valueoffset表示当前对象的偏移地址,expect表示预期值 update表示更新值。作用是如果预期值和该对象偏移地址中的值一样,就用更新值更新偏移地址中的值。 AtomicInteger类初始化 // setup to use Unsafe.compareAndSwapInt for updates private static final Unsafe unsafe = Unsafe.getUnsafe(); private static final long valueOffset; static { try { valueOffset