atomic

Java多线程对象及变量的并发访问

社会主义新天地 提交于 2020-04-28 11:20:59
目录: <a href='#1'>synchronized总结</a> <a href='#2'>写一个死锁</a> <a href='#3'>线程安全的三大特性</a> <a href='#4'>java内存模型</a> <a href='#5'>synchronized与volatile对比</a> <a href='#6'>Atomic原子类</a> <a href='#7'>CAS机制(compare and swap)</a> <a href='#8'>乐观锁悲观锁</a> 1、<herf name='1'>synchronized </a> 1.1、方法内的变量为线程安全的 “非线程安全”问题存在于实例变量中,如果一个变量是方法内的变量,那么这个变量是线程安全的,也不会出现“非线程安全”问题。 代码: package Thread.thread2; public class Num { //private int num; public void addI(String str){ int num =0; if(str.equals("a")){ num=100; System.out.println("a set over"); try { Thread.sleep(2000); } catch (InterruptedException e) { e

数据一致性 kafka 是保存副本 leader读写,follower 只备份 而 zookeeper是 leader 读写,follower负责读

試著忘記壹切 提交于 2020-04-27 18:14:47
我写了另一篇zookeeper选举机制的,可以参考: zookeeper 负载均衡 核心机制 包含ZAB协议(滴滴,阿里面试) 一、zookeeper 与kafka保持数据一致性的不同点: (1)zookeeper使用了ZAB( Zookeeper Atomic Broadcast )协议,保证了leader,follower的一致性, leader 负责数据的读写,而follower只负责数据的读 ,如果follower遇到写操作,会提交到leader; 当leader宕机的话,使用 Fast Leader Election 快速选举出新的leader, 节点在一开始都处于选举阶段, 只要有一个节点得到超半数节点的票数 ,它就可以当选准 leader。 其客户端根据链接的follower不同,可能读取到不同的数据。这是由于副本没有完全同步,存在时间差的原因。由于follower分担了读取数据的压力,zookeeper只要保留全局leader即可,不再进行细分。 如下所示:leader==》读写,follower==>只负责读; Zookeeper工作方式 》Zookeeper集群包含一个1个Leader,多个Follower 》所有的Follower都可提供读服务 》所有的写操作都会被forward到Leader 》Client与Server通过NIO通信

深度解密 Go 语言之 sync.Pool

倾然丶 夕夏残阳落幕 提交于 2020-04-27 15:23:40
最近在工作中碰到了 GC 的问题:项目中大量重复地创建许多对象,造成 GC 的工作量巨大,CPU 频繁掉底。准备使用 sync.Pool 来缓存对象,减轻 GC 的消耗。为了用起来更顺畅,我特地研究了一番,形成此文。本文从使用到源码解析,循序渐进,一一道来。 本文基于 Go 1.14 目录 是什么 有什么用 怎么用 简单的例子 fmt 包如何用 pool_test 其他 源码分析 Pool 结构体 Get pin popHead getSlow popTail Put pushHead pack/unpack GC 总结 参考资料 是什么 sync.Pool 是 sync 包下的一个组件,可以作为保存临时取还对象的一个“池子”。个人觉得它的名字有一定的误导性,因为 Pool 里装的对象可以被无通知地被回收,可能 sync.Cache 是一个更合适的名字。 有什么用 对于很多需要重复分配、回收内存的地方, sync.Pool 是一个很好的选择。频繁地分配、回收内存会给 GC 带来一定的负担,严重的时候会引起 CPU 的毛刺,而 sync.Pool 可以将暂时不用的对象缓存起来,待下次需要的时候直接使用,不用再次经过内存分配,复用对象的内存,减轻 GC 的压力,提升系统的性能。 怎么用 首先, sync.Pool 是协程安全的,这对于使用者来说是极其方便的。使用前,设置好对象的 New

CAS 理解以及总结

徘徊边缘 提交于 2020-04-27 02:21:15
简介 CAS(compare and swap) 即“比较”和“交换”,主要为了解决在多线程并发情况下,使用锁造成的性能消耗问题。在高效、不加锁的情况下,能够以原子性的行为实现数据的操作。一般系统层面都在硬件层次上直接支持CAS指令,而高级语言一般都会直接利用这些指令。 java中的CAS 在 java.util.concureent.atomic 包中拥有大量的原子类,他们都是利用了CAS来完成原子性操作。需要关注的就是它们共同都拥有的一个函数 compareAndSet(expect,update) public final boolean compareAndSet(int expect, int update) { return unsafe.compareAndSwapInt(this, valueOffset, expect, update); } 以 AtomicInteger 类中的 compareAndSet 函数为例,其他各个原子类的 compareAndSet 函数差异不大。最后调用的都是 unsafe.compareAndSwapInt 函数或者 unsafe.compareAndSwapObject 只不过一个是数值一个是引用类型而已。 compareAndSet函数 这个函数总共有两个参数, expect 和 update ,第一个代表期望值

Java面试系列第1篇-基本类型与引用类型

被刻印的时光 ゝ 提交于 2020-04-26 19:30:45
这篇文章总结一下我认为面试中最应该掌握的关于基本类型和引用类型的面试题目。 面试题目1:值传递与引用传递 对于没有接触过C++这类有引用传递的Java程序员来说,很容易误将引用类型的参数传递理解为引用传递,而基本类型的传递理解为值传递,这是错误的。要理解值传递与引用传递,首先要理清值传递、引用传递与指针传递三个概念。 值传递与引用传递最重要的就是看在传递的过程中,值是否发生了复制。在Java中没有指针的概念,但是引用类型做为参数进行传递时,JVM将其实现为指针传递,那么重点就是搞清楚指针传递到底是值传递还是引用传递了。指针在传递时也会复制,所以是值传递,Java中不存在引用传递。 面试题目2:int类型的范围 Java中4种基本类型表示的范围如下图所示。 Java中不能明确指示某个数为无符号类型,所以最高位一般为符号位。拿占一个字节的byte来说,由于最高位需要表示符号,所以只能用剩下的7位来表示数。所以最大可表示的数为 0111 1111(二进制) max = (2^0+2^1+2^2+...+2^6) = 127 最小可表示数的范围用二进制表示应该为: 1111 1111(二进制) 但是对于计算机来说,负数其实是用补码表示的,也就是反码加1,所以在计算机中存储的二进制为1000 0001(补码),这个值才是-127。 我们要对待一种特殊情况,如下: 1000 0000(原码)

一道非常棘手的 Java 面试题:i++ 是线程安全的吗?

安稳与你 提交于 2020-04-26 15:17:13
i++ 是线程安全的吗? 相信很多中高级的 Java 面试者都遇到过这个问题,很多对这个不是很清楚的肯定是一脸蒙逼。内心肯定还在质疑,i++ 居然还有线程安全问题?只能说自己了解的不够多,自己的水平有限。 先来看下面的示例来验证下 i++ 到底是不是线程安全的。 1000个线程,每个线程对共享变量 count 进行 1000 次 ++ 操作。 上面的例子我们期望的结果应该是 1000000,但运行 N 遍,你会发现总是不为 1000000,至少你现在知道了 i++ 操作它不是线程安全的了。 先来看 JMM 模型中对共享变量的读写原理吧。 每个线程都有自己的工作内存,每个线程需要对共享变量操作时必须先把共享变量从主内存 load 到自己的工作内存,等完成对共享变量的操作时再 save 到主内存。 问题就出在这了,如果一个线程运算完后还没刷到主内存,此时这个共享变量的值被另外一个线程从主内存读取到了,这个时候读取的数据就是脏数据了,它会覆盖其他线程计算完的值。。。 这也是经典的内存不可见问题,那么把 count 加上 volatile 让内存可见是否能解决这个问题呢? 答案是:不能。因为 volatile 只能保证可见性,不能保证原子性。多个线程同时读取这个共享变量的值,就算保证其他线程修改的可见性,也不能保证线程之间读取到同样的值然后相互覆盖对方的值的情况。

【并发编程】Java并发编程传送门

心已入冬 提交于 2020-04-25 16:31:37
本博客系列是学习并发编程过程中的记录总结。由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅。 并发编程系列博客传送门 背景知识 【并发编程】摩尔定律失效“带来”并行编程 【并发编程】Java对并发编程的支持历史 【并发编程】并发编程中你需要知道的基础概念 并发编程基础 【并发编程】实现多线程的几种方式 【并发编程】Thread类的详细介绍 【并发编程】Object的wait、notify和notifyAll方法 【并发编程】线程状态解析 【并发编程】ThreadLocal其实很简单 【并发编程】InheritableThreadLocal使用详解 JMM相关 【并发编程】最简单的 Java内存模型 讲解 【并发编程】Java内存模型之原子性问题 【并发编程】Java内存模型之可见性问题 【并发编程】Java内存模型之有序性问题 【并发编程】Volatile原理和使用场景解析 【并发编程】ThreadLocalRandom——Random在大并发环境下的替代者 锁技术 【并发编程】锁分类介绍 【并发编程】synchronized的使用场景和原理简介 【转载】并发编程的基石——AQS类 【并发编程】同步锁——ReentrantLock 原子操作类 【并发编程】并发编程的基石——CAS机制 【转载】Atomic系列类整体介绍 【并发编程

SDWebimage相关知识点1-- 线程

你说的曾经没有我的故事 提交于 2020-04-25 13:15:04
一 线程 (thread)是组成进程的子单元,操作系统的调度器可以对线程进行单独的调度。实际上,所有的并发编程 API 都是构建于线程之上的 —— 包括 GCD 和操作队列(operation queues)。 多线程可以在单核 CPU 上同时(或者至少看作同时)运行。操作系统将小的时间片分配给每一个线程,这样就能够让用户感觉到有多个任务在同时进行。如果 CPU 是多核的,那么线程就可以真正的以并发方式被执行,从而减少了完成某项操作所需要的总时间。 NSThread 是 Objective-C 对 pthread 的一个封装。通过封装 直接使用线程可能会引发的一个问题是,如果你的代码和所基于的框架代码都创建自己的线程时,那么活动的线程数量有可能以指数级增长。这在大型工程中是一个常见问题。例如,在 8 核 CPU 中,你创建了 8 个线程来完全发挥 CPU 性能。然而在这些线程中你的代码所调用的框架代码也做了同样事情(因为它并不知道你已经创建的这些线程),这样会很快产生成成百上千的线程。代码的每个部分自身都没有问题,然而最后却还是导致了问题。使用线程并不是没有代价的,每个线程都会消耗一些内存和内核资源。 二 GCD Grand Central Dispatch 通过 GCD,开发者不用再直接跟线程打交道了,只需要向队列中添加代码块即可,GCD 在后端管理着一个 线程池 。GCD

Java并发-多线程面试(全面)

只愿长相守 提交于 2020-04-24 20:27:13
1. 什么是线程? 2. 什么是线程安全和线程不安全? 3. 什么是自旋锁? 4. 什么是Java内存模型? 5. 什么是CAS? 6. 什么是乐观锁和悲观锁? 7. 什么是AQS? 8. 什么是原子操作?在Java Concurrency API中有哪些原子类(atomic classes)? 9. 什么是Executors框架? 10. 什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型? 11. 什么是Callable和Future? 12. 什么是FutureTask? 13. 什么是同步容器和并发容器的实现? 14. 什么是多线程?优缺点? 15. 什么是多线程的上下文切换? 16. ThreadLocal的设计理念与作用? 17. ThreadPool(线程池)用法与优势? 18. Concurrent包里的其他东西:ArrayBlockingQueue、CountDownLatch等等。 19. synchronized和ReentrantLock的区别? 20. Semaphore有什么作用? 21. Java Concurrency API中的Lock接口(Lock interface)是什么?对比同步它有什么优势? 22. Hashtable的size()方法中明明只有一条语句”return count”,为什么还要做同步? 23.

这份Java面试宝典,你值得拥有(2020版上篇)

送分小仙女□ 提交于 2020-04-24 18:39:32
一、Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,java 运行环境,为 java 的运行提供了所需环境。 具体来说 JDK 其实包含了 JRE,同时还包含了编译 java 源码的编译器 javac,还包含了很多 java 程序调试和分析的工具。 简单来说:如果你需要运行 java 程序,只需安装 JRE 就可以了,如果你需要编写 java 程序,需要安装 JDK。 2. == 和 equals 的区别是什么? == 解读 对于基本类型和引用类型 == 的作用效果是不同的,如下所示: 基本类型:比较的是值是否相同; 引用类型:比较的是引用是否相同; 代码示例: 1 String x = "string"; 2 String y = "string"; 3 String z = new String("string"); 4 System.out.println(x==y); // true 5 System.out.println(x==z); // false 6 System.out.println(x.equals(y)); // true 7 System.out.println