原子操作

Java Automic包下的AtomicInteger

人走茶凉 提交于 2019-11-28 08:13:06
感谢这两位博主的文章,文章源于: https://www.cnblogs.com/chenpi/p/5375805.html https://blog.csdn.net/fanrenxiang/article/details/80623884 版本:dk1.5后提供了,java.util.concurrent.atomic包 作用:方便程序员在多线程环境下,无锁的进行原子性操作 底层:原子变量的底层使用了处理器提供的原子指令,但是不同的CPU架构可能提供的原子指令不一样,也有可能需要某种形式的内部锁,所以该方法不能绝对保证线程不被阻塞 内部核心:Atomic包里内部实现不是简单的使用synchronized,而是一个更为高效的方式CAS (compare and swap) + volatile和native方法(同步的工作更多的交给了硬件),从而避免了synchronized的高开销,执行效率大为提升 关于CAS: compare and swap,比较和替换技术,将预期值与当前变量的值比较(compare),如果相等则使用新值替换(swap)当前变量,否则不作操作; 现代CPU已广泛支持CAS指令,如果不支持,那么JVM将使用自旋锁,与互斥锁一样,两者都需先获取锁才能访问共享资源,但互斥锁会导致线程进入睡眠,而自旋锁会一直循环等待直到获取锁; 另外

java多线程:基础原理

送分小仙女□ 提交于 2019-11-28 08:07:24
java多线程:基础原理 java支持多线程编程,为了能够深入理解java多线程机制,以及解决多线程的安全问题,本文介绍多线程的基础知识和原理分析。 Part1 概念总结 线程的概念 线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。 线程vs进程: A.多个进程的内部数据和状态都是完全独立的,(进程就是执行中的程序,程序是静态的概念,进程是动态的概念)。而多线程是共享一块内存空间和一组系统资源的,有可能互相影响(多个线程可以在一个进程中) B.线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程切换的负担要小。 多线程编程 在单个程序中可以同时运行多个不同的线程执行不同的任务。但是具体执行哪个线程是由cpu随机决定的。 多线程编程的目的,就是“最大限度地利用CPU资源”,当某一线程的处理不需要占用CPU而只和I/O等资源打交道时

JUC

你。 提交于 2019-11-28 06:24:05
JUC 回顾 1 NIO主要内容:Buffer、Channel 2 非阻塞式网络编程 今天任务 1 volatile的使用 2 原子变量和CAS算法 3 Lock接口 4 并发集合 5 同步工具类 第一节 JUC 概述 在 Java 5.0 提供了 java.util.concurrent(简称JUC)包,在此包中增加了在并发编程中很常用的工具类, 用于定义类似于线程的自定义子系统,包括线程池,异步IO和轻量级任务框架;还提供了用于多线程上下文中的 Collection实现等。 第二节 volatile volatile:易变的,不稳定的 在并发编程中的三个特性: (1)互斥性(原子性) (2)内存可见性 (3)指令重排序 int b=20; int a=10; int c=a+b; volatile 关键字: 当多个线程进行操作共享数据时,可以保证内存中的数据是可见的;相较于 synchronized 是一种较为轻量级的同步策略; volatile 不具备"互斥性"; volatile 不能保证变量的"原子性"; synchronized和volatile的区别: (1)synchronized可以实现互斥性和内存可见性,不能禁止指令重排序。 (2)volatile可以实现内存可见性,禁止指令重排序,不能保证原子性。 案例演示:内存可见性 public class

Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

心不动则不痛 提交于 2019-11-28 04:55:48
首先介绍一些乐观锁与悲观锁:   悲观锁:总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。再比如 Java里面的同步原语 synchronized关键字的实现也是悲观锁 。   乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁, 但是在更新的时候会判断一下在此期间别人有没有去更新这个数据 ,可以使用版本号等机制。 乐观锁适用于多读的应用类型 ,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在 Java中java.util.concurrent.atomic包下面的 原子变量类就是使用了乐观锁的一种实现方式CAS实现的 。 乐观锁的一种实现方式-CAS(Compare and Swap 比较并交换):   锁存在的问题:      Java在JDK1.5之前都是靠 synchronized关键字保证同步的 ,这种通过使用一致的锁定协议来协调对共享状态的访问,可以确保无论哪个线程持有共享变量的锁,都采用独占的方式来访问这些变量。这就是一种独占锁,独占锁其实就是一种悲观锁,所以可以说 synchronized 是悲观锁。  

Java并发编程--Volatile详解

北城余情 提交于 2019-11-28 02:28:23
摘要 Volatile是Java提供的一种弱同步机制,当一个变量被声明成volatile类型后编译器不会将该变量的操作与其他内存操作进行重排序。在某些场景下使用volatile代替锁可以减少代码量和使代码更易阅读。 Volatile特性 1.可见性:当一条线程对volatile变量进行了修改操作时,其他线程能立即知道修改的值,即当读取一个volatile变量时总是返回最近一次写入的值 2.原子性:对于单个voatile变量其具有原子性(能保证long double类型的变量具有原子性),但对于i ++ 这类复合操作其不具有原子性(见下面分析) 使用volatile变量的前提 1.对变量的写入操作不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值 2.该变量不会与其他状态变量一起纳入不变性条件中 3.在访问变量时不需要加锁 volatile可见性 volatile的可见性正是基于happend -before(先行发生)关系实现的。 happend-before:java内存模型有八条可以保证happend-before的规则(详见《深入理解Java虚拟机》P376),如果两个操作之间的关系无法从这八条规则中推导出来的话,它们就没有顺序保障,虚拟机就可以对它们随意地进行重排序. 其中就包含”volatile变量规则“

并发之原子性、可见性、有序性

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

Java内存模型

蹲街弑〆低调 提交于 2019-11-27 21:19:06
Java内存模型 最近,面试过很多Java中高级开发,问过很多次关于Java内存模型的知识,问完之后,很多人上来就开始回答: Java内存模型由几部分组成,堆、本地方法栈、虚拟机栈、方法区… 每一次我不想打断他们的话,虽然我知道这又是一个误会了我的问题的朋友。 其实, 我想问的Java内存模型,是和并发编程有关的 。 而候选人给我回答的那叫JVM内存结构,完全是两回事。 很多时候,在我没有打断他们的情况下,一部分人慢慢的讲到了GC相关的知识。这种情况下,我只能硬着头皮继续问一些和JVM有关的知识。 但是,我的本意其实是想看一下他对Java并发有多少了解啊。 经常,我都在继续追问了一些他们回答的"Java内存模型"相关的知识后,友善的提醒一句,其实我想问的Java内存模型并不是他回答的这个… 有的时候,我会进一步提醒一句:是和并发编程有关的,是和主内存以及线程工作内存有关的。。。 那么,本文就来简单说一说,关于Java内存模型,到底应该如何回答这个面试题。 1 为什么会误解 首先,我们先来分析一下问什么很多人,甚至是大多数人会答非所问呢? 我觉得主要有几个原因: 1、Java内存模型,这个词听着太像是关于内存分布的知识了。听上去和并发编程没有半毛钱关系。 2、 网上很多资料都是错的 。不信你去网上搜索一下"Java内存模型",你会发现,很多人打着内存模型的标题

vue 中使用particles.js

时光总嘲笑我的痴心妄想 提交于 2019-11-27 19:18:10
1. particles.js 是什么? --- 轻量级JavaScript粒子库 , gitHub 地址可以下载示例代码,示例代码为DOM开发形式: https://github.com/VincentGarreau/particles.js 2. 效果就不给看了,公司的内部网站。直接上代码 //(1) 下载particles.js npm install particles.js --save //(2) 在template里面写一个div作为粒子库的容器 ,就像canvas那样 <div id="particlesId"></div> //(3) 创建粒子库的配置文件,particles.json , 建议放在public静态资源文件夹 https://www.jb51.net/article/123527.htm 这个配置地址里有两个,我认为不好看 http://www.jq22.com/jquery-info20054 这个里面很漂亮,配置参数注释详细 为了方便,我直接将我认为漂亮的配置particles.json粘贴过来 { "particles": { "number": { "value": 160,//数量 "density": { "enable": true, //启用粒子的稀密程度 "value_area": 800 //区域散布密度大小 } },

12.Unsafe原子性操作

☆樱花仙子☆ 提交于 2019-11-27 15:33:32
import sun.misc.Unsafe; /** * JDK8 * JDK 的此jar 包中的 Unsafe 类提供了硬件级别的原子性操作 */ public class UnsafeTest { //获得Unsafe的一个实例 static final Unsafe unsafe1 = Unsafe.getUnsafe(); static final long stateOffset; private volatile long state = 0; static { try { //获取 UnsafeTest 类里面的 state 变量, 在 UnsafeTest 对象里面的内存偏移量地址并将其保存到 stateOffset 变量中。 //getDeclaredFields():获得某个类的所有声明的字段 stateOffset = unsafe1.objectFieldOffset(UnsafeTest.class.getDeclaredField("state")); } catch (NoSuchFieldException e) { System.out.println(e.getLocalizedMessage()); throw new Error(e); } } public static void main(String[] args){

说一说JMM(java内存模型)是什么

空扰寡人 提交于 2019-11-27 14:56:45
java内存模型 面试中,经常会被问到什么是java内存模型,有的人就会回答成JVM内存模型,这样是错误的,在面试中只要弄清楚问的是JMM还是JVM就好了。 什么是内存模型: Java内存模型是根据英文Java Memory Model(JMM)翻译过来的。其实JMM并不像JVM内存结构一样是真实存在的。他只是一个抽象的概念。 Java内存模型的相关知识在 JSR-133: Java Memory Model and Thread Specification 中描述的。JMM是和多线程相关的,他描述了一组规则或规范,这个规范定义了一个线程对共享变量的写入时对另一个线程是可见的。 Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能得到一致效果的机制及规范。目的是解决由于多线程通过共享内存进行通信时,存在的原子性、可见性(缓存一致性)以及有序性问题。 那么,我们这里就先来说说什么是所谓的内存模型规范、这里提到的原子性、可见性以及有序性又是什么东西? 原子性 线程是CPU调度的基本单位。CPU有时间片的概念,会根据不同的调度算法进行线程调度。所以在多线程场景下,就会发生原子性问题。因为线程在执行一个读改写操作时,在执行完读改之后,时间片耗完,就会被要求放弃CPU