原子操作

Java内存模型(JMM)

本小妞迷上赌 提交于 2019-12-05 04:27:20
JVM与线程(线程在JVM中) 1、JVM什么时候启动? 类被调用时启动,此时会启动JVM线程然后再是其他的线程(main) 2、JVM内存区域 除了程序计数器(PC)之外都有可能发生内存溢出 方法区:类信息、常量、static 、JIT 、(信息共享)(OOM) Java堆区:实例对象、GC、(信息共享) (OOM) VM stack:Java方法在运行的内存模型 (OOM) PC:java线程的私有数据,这个数据就是执行下一条指令的地址 Native method stack: 与JVM的native(00M) 3、Java内存模型 Java memory model JMM(规范,抽象的模型) 1)主内存:共享的信息 2)工作内存:私有信息,基本数据类型,直接分配到工作内存,引用的地址存放在工作内存,引用的对象存放在堆中 3)工作方式: A 线程修改私有数据,直接在工作空间修改 B 线程修改共享数据,把数据复制到工作空间中去,在工作空间中修改,修改完成以后,刷新内存中的数据 4、硬件内存架构与java内存模型 1)硬件架构 a)CPU缓存的一致性问题:并发处理的不同步 b)解决方案: i.总线加锁() 降低CPU的吞吐量 ii.缓存上的一致性协议(MESI) 当CPU在CACHE中操作数据时,如果该数据是共享变量,数据在CACHE读到寄存器中,进行新修改,并更新内存数据

Kafka设计解析(八)- Kafka事务机制与Exactly Once语义实现原理

 ̄綄美尐妖づ 提交于 2019-12-05 02:14:05
写在前面的话 本文所有Kafka原理性的描述除特殊说明外均基于Kafka 1.0.0版本。 为什么要提供事务机制 Kafka事务机制的实现主要是为了支持 Exactly Once 即正好一次语义 操作的原子性 有状态操作的可恢复性 Exactly Once 《 Kafka背景及架构介绍 》一文中有说明Kafka在0.11.0.0之前的版本中只支持 At Least Once 和 At Most Once 语义,尚不支持 Exactly Once 语义。 但是在很多要求严格的场景下,如使用Kafka处理交易数据, Exactly Once 语义是必须的。我们可以通过让下游系统具有幂等性来配合Kafka的 At Least Once 语义来间接实现 Exactly Once 。但是: 该方案要求下游系统支持幂等操作,限制了Kafka的适用场景 实现门槛相对较高,需要用户对Kafka的工作机制非常了解 对于Kafka Stream而言,Kafka本身即是自己的下游系统,但Kafka在0.11.0.0版本之前不具有幂等发送能力 因此,Kafka本身对 Exactly Once 语义的支持就非常必要。 操作原子性 操作的原子性是指,多个操作要么全部成功要么全部失败,不存在部分成功部分失败的可能。 实现原子性操作的意义在于: 操作结果更可控,有助于提升数据一致性 便于故障恢复。因为操作是原子的

多线程之美1一volatile

假装没事ソ 提交于 2019-12-04 21:12:28
摘自: https://www.cnblogs.com/flydashpig/p/11875652.html 多线程之美1一volatile 目录 一、java内存模型 1.1、抽象结构图 1.2、概念介绍 二、volatile详解 2.1、概念 2.2、保证内存可见性 2.3、不保证原子性 2.4、有序性 一、java内存模型 1.1、抽象结构图 1.2、概念介绍 java 内存模型 即Java memory model(简称JMM), java线程之间的通信由JMM控制,决定一个线程对共享变量的写入何时对另一个线程可见。 多线程通信通常分为2类:共享内存和消息传递 JMM采用的就是共享内存来实现线程间的通信,且通信是隐式的,对程序开发人员是透明的,所以在了解其原理了,才会对线程之间通信,同步,内存可见性问题有进一步认识,避免开发中出错。 线程之间如何通信? 在java中多个线程之间要想通信,如上图所示,每个线程在需要操作某个共享变量时,会将该主内存中这个共享变量拷贝一份副本存在在自己的本地内存(也叫工作内存,这里只是JMM的一个抽象概念,即将其笼统看做一片内存区域,用于每个线程存放变量,实际涉及到缓存,寄存器和其他硬件),线程操作这个副本,比如 int i = 1;一个线程想要进行 i++操作,会先将变量 i =1 的值先拷贝到自己本地内存操作,完成 i++,结果 i=2

【转】Mysql中事务ACID实现原理

时光怂恿深爱的人放手 提交于 2019-12-04 18:58:32
转自: https://www.cnblogs.com/rjzheng/p/10841031.html 作者:孤独烟 引言 照例,我们先来一个场景~ 面试官:"知道事务的四大特性么?" 你:"懂,ACID嘛,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)!" 面试官:"你们是用mysql数据库吧,能简单说说innodb中怎么实现这四大特性的么?“ 你:"我只知道隔离性是怎么做的balabala~~" 面试官:"还是回去等通知吧~" OK,回到正题。说到事务的四大特性原子性( Atomicity )、一致性( Consistency )、隔离性( Isolation )、持久性( Durability ),懂的人很多。但是稍微涉及细节一点,这四大特性在数据库中的实现原理是怎么样的?那就没有几个人能够答得上来了。因此,我们这篇文章着重讨论一下四大特性在Mysql中的实现原理。 正文 我们以从A账户转账50元到B账户为例进行说明一下ACID,四大特性。 原子性 根据定义,原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做。即要么转账成功,要么转账失败,是不存在中间的状态! 如果无法保证原子性会怎么样? OK,就会出现 数据不一致 的情形,A账户减去50元,而B账户增加50元操作失败

CAS-原子操作

佐手、 提交于 2019-12-04 15:22:47
一 概念 在计算机中比较和交换(Conmpare And Swap 即 CAS)是用于实现多线程同步的原子指令,当多个线程对某个资源进行CAS操作,只能有1个线程成功,其他线程并不会阻塞而是返回失败信号。 二 基本原理 每个CAS包含3个运算符 1 内存地址 V 2 旧的预期值A 3 新增B 基本思路,如果V地址上的值和传入的旧的期望值A相等,就给地址赋个新值B,否则不做任何处理 if(V.value.equals(A)){ V.value = B; return true;}else{ return false;} 常用 原子操作类型基本类型 AtomicInteger,AtomicLong,AtomicBoolean;数组类型 AtomicIntegerArray,AtomicLongArray,AtomicReferenceArray;引用类型 AtomicReference,AtomicMarkableReference,AtomicStampedReference 三 常见用法和ABA问题 3.1 常见用法 原子操作基本类型(Integer) AtomicInteger atomicInteger = new AtomicInteger(10);//基本类型原子操作测试public void atomicIntegerTest(){ //自增1 并返回新值 System

并发

匆匆过客 提交于 2019-12-04 15:07:15
1.Java线程有优先级 :1~10 static int MAX_PRIORITY:线程可以具有的最高优先级,取值为 10。 static int MIN_PRIORITY:线程可以具有的最低优先级,取值为 1。 static int NORM_PRIORITY:分配给线程的默认优先级,取值为 5。 使用: 主线程优先级为normal;优先级有继承关系,A线程中创建B线程,那么A,B同样优先级 Thread4 t1 = new Thread4( "t1"); t1 .setPriority( Thread .MAX_PRIORITY); //这里设置具体数值也是可以的 getPriority可以获取线程优先级 1.1线程睡眠 不释放锁 sleep():使线程转为阻塞状态,当sleep结束后,转为就绪 1.2线程等待object中的方法 释放锁 wait():当前线程等待,释放锁,直到其他线程调用此对象的notify()方法或notifyAll()唤醒方法,行为等价于wait(0) 1.3线程让步 不释放锁 yield():暂停当前正在执行的对象,把执行机会让给相同或者更高优先级的线程 1.4线程加入 join() :当前线程调用另一个线程的jion()方法,当前线程进入阻塞状态,直到另一个进程运行结束,当前才阻塞—>就绪 1.5线程唤醒 notify()与notifyAll()

深入CAS的底层实现机制,以及对应的使用风险

独自空忆成欢 提交于 2019-12-04 14:18:50
概述 CAS(Compare-and-Swap),即比较并替换,是一种实现并发算法时常用到的技术,Java并发包中的很多类都使用了CAS技术。CAS也是现在面试经常问的问题,本文将深入的介绍CAS的原理。 案例 介绍CAS之前,我们先来看一个例子。 /** * @author joonwhee * @date 2019/7/6 */ public class VolatileTest { public static volatile int race = 0; private static final int THREADS_COUNT = 20; public static void increase() { race++; } public static void main(String[] args) throws InterruptedException { Thread[] threads = new Thread[THREADS_COUNT]; for (int i = 0; i < THREADS_COUNT; i++) { threads[i] = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10000; i++) { increase(); } } })

JDK中原子性的支持

纵饮孤独 提交于 2019-12-04 13:24:18
在Java开发中,假设对共享变量除了赋值之外并不完成其他操作, 那么可以将这些共享变量声明为 volatile 或者final。 然而经常我们除了对共享变量赋值之外,还需要对共享变量进行修改操作,比如自增,自减等系列操作,那么此时就需要保证共享变量的 原子性 ,所谓原子性,就是站在机器的角度,一个不可分隔的执行单元。在JDK中,java.util.concurrent.atomic 包中有很多类使用了很高效的机器级指令(而不是使用 锁) 来保证其他操作的原子性。 比如说AtomicLong类,提供了方法 incrementAndGet 和 decrementAndGet, 它们分别以原子方式将一个整数自增或自减。例如, 可以安全地生成一个 数值序列,像这样: public static AtomicLong atomicLong = new AtomicLong(1); public static void main(String[] args) { long res = atomicLong.incrementAndGet(); System.out.println(res); } incrementAndGet 方法以原子方式将 AtomicLong 自增, 并返回自增后的值。 也就是说, 获得值、 增 1 并设置然后生成新值的操作不会中断。

深入Synchronized的实现原理与源码分析

Deadly 提交于 2019-12-04 04:36:59
前言 一、synchronized的特性 1.1 原子性 1.2 可见性 1.3 有序性 1.4 可重入性 二、synchronized的用法 三、synchronized锁的实现 3.1 同步方法 3.2 同步代码块 四、synchronized锁的底层实现 五、JVM对synchronized的优化 5.1 锁膨胀 5.1.1 偏向锁 5.1.2 轻量级锁 5.1.3 重量级锁 5.2 锁消除 5.3 锁粗化 5.4 自旋锁与自适应自旋锁 结语 前言 如果某一个资源被多个线程共享,为了避免因为资源抢占导致资源数据错乱,我们需要对线程进行同步,那么synchronized就是实现线程同步的关键字,可以说在并发控制中是必不可少的部分,今天就来看一下synchronized的使用和底层原理。 一、synchronized的特性 1.1 原子性 所谓原子性就是指一个操作或者多个操作,要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行。但是像i++、i+=1等操作字符就不是原子性的,它们是分成 读取、计算、赋值 几步操作,原值在这些步骤还没完成时就可能已经被赋值了,那么最后赋值写入的数据就是脏数据,无法保证原子性。

Java内存模型相关原则详解

假如想象 提交于 2019-12-03 17:13:30
在《 Java内存模型(JMM)详解 》一文中我们已经讲到了Java内存模型的基本结构以及相关操作和规则。而Java内存模型又是围绕着在并发过程中如何处理原子性、可见性以及有序性这三个特征来构建的。本篇文章就带大家了解一下相关概念、原则等内容。 原子性 原子性即一个操作或一系列是不可中断的。即使是在多个线程的情况下,操作一旦开始,就不会被其他线程干扰。 比如,对于一个静态变量int x两条线程同时对其赋值,线程A赋值为1,而线程B赋值为2,不管线程如何运行,最终x的值要么是1,要么是2,线程A和线程B间的操作是没有干扰的,这就是原子性操作,不可被中断的。 Java内存模型对以下操作保证其原子性:read,load,assign,use,store,write。我们可以大致认为基本数据类型的访问读写是具备原子性的(前面也提到了long和double类型的“半个变量”情况,不过几乎不会发生)。 从Java内存模型底层来看有上面的原子性操作,但针对用户来说,也就是我们编写Java的程序,如果需要更大范围的原子性保障,就需要同步关键字——synchronized来保障了。也就是说synchronized中的操作也具有原子性。 可见性 可见性是指当一个线程修改了共享变量的值,其他线程能够立即得知这个修改。 Java内存模型是通过变量修改后将新值同步回主内存,在变量读取前从主内存刷新变量值