CAS

这或许是最详细的JUC多线程并发总结

女生的网名这么多〃 提交于 2020-07-27 12:20:09
多线程进阶---JUC并发编程 完整代码传送门,见文章末尾 1.Lock锁(重点) 传统 Synchronizd package com.godfrey.demo01; /** * description : 模拟卖票 * * @author godfrey * @since 2020-05-14 */ public class SaleTicketDemo01 { public static void main(String[] args) { Ticket ticket = new Ticket(); new Thread(() -> { for (int i = 0; i < 60; i++) { ticket.sale(); } }, "A").start(); new Thread(() -> { for (int i = 0; i < 60; i++) { ticket.sale(); } }, "B").start(); new Thread(() -> { for (int i = 0; i < 60; i++) { ticket.sale(); } }, "C").start(); } } //资源类OOP class Ticket { private int number = 50; public synchronized void sale() { if

新特性解读 | mysql 8.0 memcached api 新特性

筅森魡賤 提交于 2020-07-27 11:52:04
作者:杨涛涛 资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。 本文来源:原创投稿 *爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。 本文关键字:memcached 一款优秀的缓存系统 memcache 本身是一款分布式的高速缓存系统,以 key-value 的形式常驻内存,一般用来做网站或者数据库的缓存使用。 特别是对以下场景非常适合用 memcache 来做缓存: 频繁访问的数据 安全性要求比较低的数据 更新比较频繁的小表(用户状态表、物品库存等) MySQL memcached api MySQL 5.6 —— 开始支持 MySQL 5.6 把 memcache 功能以插件形式集成到 MySQL 数据库中,称为 memcached api。 这样一来,memcache 的数据以 InnoDB 关系表的形式同步于磁盘,解决了 memcache 的几个问题: 解决了 memcache 的数据持久化的问题; 可以很方便的以 SQL 语句的形式直接访问 memcache 的数据; 不需要单独安装 memcache,安装 MySQL

多线程与高并发四:VarHandle与强软弱虚引用和ThreadLocal

空扰寡人 提交于 2020-07-27 09:00:27
文章目录 1:VarHandle 2:强软弱虚引用 2.1. 强引用 2.2. 软引用(SoftReference) 2.3. 弱引用(WeakReference) 2.4. 虚引用(PhantomReference):管理堆外内存 3:ThreadLocal 3.1:线程本地 3.2:原理 3.3:ThreadLocal与:弱引用的配合使用 1:VarHandle 上一篇说了AQS的源码,其中还有一个知识点VarHandle,看下面的代码 大家会问:VarHandle是什么?有什么作用? 其实: VarHandle是jdk1.9之后才出现的,表示指向某个变量的引用,可以完成原子性的线程安全操作可以通过cas方式进行比较设值。比反射快,直接操纵二进制码,反射每次操作前都要做检查 2:强软弱虚引用 博客部分内容引用: http://blog.csdn.net/liuxian13183 2.1. 强引用 Object object=new Object();那object就是一个强引用了。如果一个对象具有 强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题 。 2.2. 软引用(SoftReference) 如果一个对象只具有*

Java并发编程(五):synchronized原理详解及锁优化

僤鯓⒐⒋嵵緔 提交于 2020-07-27 06:58:50
文章目录 1 引言 2 synchronized实现原理 2.1 监视器锁(monitor)机制 2.1.1 作用在方法上 2.1.2 作用在代码块 2.2 获取锁和释放锁的内存语义 3 synchronized的锁优化 3.1 JVM中对象的内存区域 3.2 偏向锁 3.2.1 偏向锁的获取 3.2.2 偏向锁的撤销 3.3 轻量级锁 3.3.1 加锁 3.3.2 解锁 3.4 各种锁的比较 3.5 小结 点点关注,不会迷路 1 引言 线程运行时拥有自己 私有的栈空间 ,会在自己的栈空间运行,如果多线程间没有共享的数据也就是说多线程间并没有协作完成一件事情,那么,多线程就不能发挥优势,不能带来巨大的价值。那么共享数据的线程安全问题怎样处理?很自然而然的想法就是每一个线程依次去读写这个共享变量,这样就不会有任何数据安全的问题,因为每个线程所操作的都是当前最新的版本数据。那么,在 Java关键字synchronized就具有使每个线程依次排队操作共享变量的功能 。很显然,这种同步机制效率很低,但synchronized是其他并发容器实现的基础,对它的理解大有裨益。 2 synchronized实现原理 在Java代码中,synchronized可使用在代码块和方法中,synchronized的使用场景如下: 如图,synchronized可以用在 方法 上也可以使用在 代码块 中

99 道 Java 多线程面试题,看完我跪了!

醉酒当歌 提交于 2020-07-27 01:24:00
今天给大家更新的是一篇关于多线程面试的文章,是根据时下热门的面试内容给大家进行总结的,如有雷同,请多见谅。 本篇文章属于干货内容!请各位读者朋友一定要坚持读到最后,完整阅读本文后相信你对多线程会有不一样感悟,下次面试和面试官也能杠一杠相关内容了。 1.什么是进程? 进程是系统中正在运行的一个程序,程序一旦运行就是进程。 进程可以看成程序执行的一个实例。进程是系统资源分配的独立实体,每个进程都拥有独立的地址空间。一个进程无法访问另一个进程的变量和数据结构,如果想让一个进程访问另一个进程的资源,需要使用进程间通信,比如管道,文件,套接字等。 2.什么是线程? 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。 3.线程的实现方式? 1.继承Thread类 2.实现Runnable接口 3.使用Callable和Future 4.Thread 类中的start() 和 run() 方法有什么区别? 1.start()方法来启动线程,真正实现了多线程运行。这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码;通过调用Thread类的start()方法来启动一个线程, 这时此线程是处于就绪状态, 并没有运行。然后通过此Thread类调用方法run(

老白学编程-GCC的原子操作

二次信任 提交于 2020-07-26 19:08:07
记录数值原子操作 背景 c/c++ 中, ++或-- 又或是赋值, 都不是原子操作,多线程时,使用锁和互斥量又太重,对性能造成一定损失。 原子操作API 为了提高赋值操作的效率,gcc提供了一组api,通过汇编级别的代码来保证赋值类操作的原子性,相对于涉及到操作系统系统调用和应用层同步的锁和互斥量,这组api的效率要高很多。 n++类 type __sync_fetch_and_add(type *ptr, type value, ...); // m+n type __sync_fetch_and_sub(type *ptr, type value, ...); // m-n type __sync_fetch_and_or(type *ptr, type value, ...); // m|n type __sync_fetch_and_and(type *ptr, type value, ...); // m&n type __sync_fetch_and_xor(type *ptr, type value, ...); // m^n type __sync_fetch_and_nand(type *ptr, type value, ...); // (~m)&n /* 对应的伪代码 */ { tmp = *ptr; *ptr op= value; return tmp; }

单点登录终极方案之 CAS 应用及原理

倖福魔咒の 提交于 2020-07-26 12:08:58
作者:Readiay https://blog.csdn.net/Readiay/article/details/52856510 Cookie的单点登录的实现方式很简单,但是也问题颇多。例如:用户名密码不停传送,增加了被盗号的可能。另外,不能跨域! 1、基于Cookie的单点登录的回顾 基于Cookie的单点登录核心原理: 将用户名密码加密之后存于Cookie中,之后访问网站时在过滤器(filter)中校验用户权限,如果没有权限则从Cookie中取出用户名密码进行登录,让用户从某种意义上觉得只登录了一次。 **该方式缺点就是多次传送用户名密码,增加被盗风险,以及不能跨域。**点击 这里 了解Java如何进行跨域。同时www.qiandu.com与mail.qiandu.com同时拥有登录逻辑的代码,如果涉及到修改操作,则需要修改两处。 2、统一认证中心方案原理 在生活中我们也有类似的相关生活经验,例如你去食堂吃饭,食堂打饭的阿姨(www.qiandu.com)告诉你,不收现金。并且告诉你,你去门口找换票的(passport.com)换小票。于是你换完票之后,再去找食堂阿姨,食堂阿姨拿着你的票,问门口换票的,这个票是真的吗?换票的说,是真的,于是给你打饭了。 基于上述生活中的场景,我们将基于Cookie的单点登录改良以后的方案如下: 经过分析,Cookie单点登录认证太过于分散

ConcurrentHashMap原理分析(1.7与1.8)-put和 get 需要执行两次Hash 多线程一起put的自旋锁问题还有 计算size 先不加锁计算3次,如果不对再给每个segme...

你。 提交于 2020-07-25 15:41:22
hashmap的扩容因子是0.75 原因 参考: HashMap默认加载因子为什么选择0.75?(阿里) ConcurrentHashMap 与HashMap和Hashtable 最大的不同在于:put和 get 两次Hash到达指定的HashEntry,第一次hash到达Segment,第二次到达Segment里面的Entry,然后在遍历entry链表 (1) 从1.7到1.8版本,由于HashEntry从链表 变成了红黑树所以 concurrentHashMap的时间复杂度从O(n)到O(log(n)) (2) HashEntry最小的容量为2 (3) concurrentHashMap 的1.7版本的 Segment ,它的初始化容量是16; (4)HashEntry在1.8中称为Node,链表转红黑树的值是8 ,当Node链表的节点数大于8时Node会自动转化为TreeNode,会转换成红黑树的结构( 阿里面试问的问题 ) 总结与思考 其实可以看出JDK1.8版本的ConcurrentHashMap的数据结构已经接近HashMap,相对而言,ConcurrentHashMap只是增加了同步的操作来控制并发,从JDK1.7版本的ReentrantLock+Segment+HashEntry,到JDK1.8版本中synchronized+CAS+HashEntry+红黑树

线程池执行器ThreadPoolExecutor源码完整解读

前提是你 提交于 2020-07-24 16:38:49
1 前言 ThreadPoolExecutor 的基本概念和用法已经在之前的文章 线程池ThreadPoolExecutor简介 、 Executor框架完整解读 中做过详细的说明,这里主要基于JDK1.8对 ThreadPoolExecutor 从源码级别分析其实现原理。 ThreadPoolExecutor 是 ExecutorService 的最重要的实现类, ThreadPoolExecutor 不直接实现 ExecutorService 接口,它直接继承于 AbstractExecutorService 抽象类 (AbstractExecutorService的源码实现在 AbstractExecutorService源码完全解析 已做过分析。) , AbstractExecutorService 对 ExecutorSerivice 接口中的一些方法做过的默认实现 。 线程池有两个重要的概念一个是任务队列,另一个是工作者线程 。 任务队列是存放任务的容器,工作者线程会依次不断地到队列中获取任务并执行。 2 重要的成员内部类 Worker Worker 继承于 AbstractQueuedSynchronizer 抽象类,它又实现了 Runnable 接口。 Worker可以理解为一个工作者线程,但内部属性又不只有一个Thread属性,除此之外还有首任务firstTask

原子性、可见性、有序性解决方案

偶尔善良 提交于 2020-07-24 16:31:49
原子性、可见性、有序性解决方案 (一)原子性 原子性是指:一个或多个操作,要么全部执行且在执行过程中不被任何因素打断,要么全部不执行。在Java中当我们讨论一个操作具有原子性问题是一般就是指这个操作会被线程的随机调度打断。 JMM对原子性的保证大概分以下几种类型:java自带原子性、synchronized、Lock锁、原子操作类(CAS)。下面我们来一个一个细说。 1. java自带原子性 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,但是long和double类型是64位,在32位JVM中会将64位数据的读写操作分成两次32位来处理,所以long和double在32位JVM中是非原子操作,也就是说在并发访问时是非线程安全的。 尤其要注意,这里我们讲的仅仅是读取和赋值两种操作具有原子性。这里的赋值仅仅指具体数值的赋值,而不包括变量给变量赋值。另外,组合操作(例如++和–操作)也同样不具有原子性。我们可以看几个经典例子: a = true ; // 原子性 a = 5 ; // 原子性 a = b ; // 非原子性,分两步完成,第一步加载b的值,第二步将b赋值给a a = b + 2 ; // 非原子性,分三步完成 a ++ ; // 非原子性,分三步完成 了解汇编语言的朋友很容易理解下面三个例子为什么不能一步完成。不了解汇编语言的朋友记住即可,这个地方非常关键