并发
文章平均质量分 70
EmineWang
计算机专业,资深java开发工程师,从事后端开发、架构方向,热爱技术,热爱分享,愿对你有所帮助,感恩大家的支持,欢迎来信交流~~
展开
-
cas原理和volatile
文章目录volatile为什么不能保证原子性?cas 原理?cas原理cas缺点CAS包含哪些参数:循环CAS:double check 单例模式中,变量为什么定义成volatile?volatile为什么不能保证原子性?1.首先volatile可以保证变量每次读的都是最新值。但是在并发操作中,向i++,这种操作不是原子性,因为这里涉及到了多个操作,1.线程A 获取i的值100,这个时候获取的是最新值,此时由于线程阻塞等原因,线程B获取的最新值100,然后将i 自增到101,更新到内存。此时线程A又来原创 2022-03-02 17:49:37 · 1385 阅读 · 0 评论 -
AQS实现原理看这一篇就够了
在上一篇中我们讲解了synchronized,在jdk1.6之前,synchronized这个重量级锁性能一直较为低下,在1.6之后,进行了大量的锁的优化,如偏向锁、自旋锁等,但是与Lock相比,synchronized还是存在一下缺陷,缺少了获取锁和释放锁的可操作性,可中断、超时获取锁,且他为独占式在高并发场景下性能大大折扣。使用Lock必然离不开核心组件AQS什么是AQSAQS(AbstractQueuedSynchronizer),即队列同步器,它是构建锁或者其他同步组件的基础框架,如Reent原创 2020-08-18 18:00:29 · 3796 阅读 · 8 评论 -
锁对象、偏向锁、轻量级锁、重量级锁
锁对象在java中任何一个对象都能成为锁对象,java对象在内存中的存储结构主要有以下三个部分:1、对象头2、实例数据3、填充数据对象头的数据主要是一些运行时的数据,其简单结构如下长度内存说明32/64bitmark wordhashcode,GC分代年龄,锁信息32/64bitclass metadata address指向对象类型数据的指针32/64bitarray Length数组的长度(当对象为数组时候)从上面可以看出锁的信息是存储在对原创 2020-08-06 16:12:49 · 726 阅读 · 0 评论 -
java8的七个阻塞队列
阻塞队列七种阻塞队列ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueDelayQueueSynchronousQueueLinkedTransferQueueLinkedBlockingDeque阻塞队列的操作方法插入操作移除操作ArrayBlockingQueue原理分析七种阻塞队列ArrayBlockingQueue数组实现的有界阻塞队列,此队列按照先进先出FIFO原则对元素进行排序LinkedBlockingQueue链表实原创 2021-03-16 17:08:11 · 573 阅读 · 0 评论 -
wait为什么要放在同步块中
且看下面一段不加锁的代码:public class WaitTest3 { public static void main(String[] args) { final String obj = "xx"; final Thread t1 = new Thread("t1") { @Override p...原创 2019-12-02 17:32:37 · 626 阅读 · 0 评论 -
BIO、NIO、AIO
在比较这两个模式之前,我们首先的搞明白几个概念,什么是阻塞和非阻塞,什么是同步和异步,同步和异步是针对应用程序和内核的交互而言的,同步指的是用户进程触发IO操作并等待或者轮询的去查看IO操作是否就绪,而异步是指用户进程触发IO操作以后便开始做自己的事情,而当IO操作已经完成的时候会得到IO完成的通知。而阻塞和非阻塞是针对于进程在访问数据的时候,根据IO操作的就绪状态来采取的不同方式,说白了是一种读取或者写入操作函数的实现方式,阻塞方式下读取或者写入函数将一直等待,而非阻塞方式下,读取或者写入函数会立即返..原创 2021-04-11 16:45:14 · 94 阅读 · 0 评论 -
顺序读写和随机读写区别和实现
顺序IO和随机IO对于磁盘的读写分为两种模式,顺序IO和随机IO。 随机IO存在一个寻址的过程,所以效率比较低。而顺序IO,相当于有一个物理索引,在读取的时候不需要寻找地址,效率很高。Java中的随机读写在Java中读写文件的方式有很多种,先总结以下3种方法:比如:public static void fileWrite(String filePath, String content) { FileOutputStream outputStream = null; try {原创 2021-11-25 17:45:04 · 15890 阅读 · 0 评论 -
【限流】Redis和Lua脚本实现令牌桶算法
参考rateLimiter实现,触发式添加令牌。取令牌的时候,通过计算上一次添加令牌和当前的时间差,计算出这段时间应该添加的令牌数,然后往桶里加,curr_mill_second = 当前毫秒数last_mill_second = 上一次添加令牌的毫秒数r = 添加令牌的速率reserve_permits = (curr_mill_second-last_mill_second)/1000 * r脚本编写添加完令牌之后再执行取令牌逻辑— 获取令牌— 返回码— 0 没有令牌桶配置— -1原创 2021-11-23 18:11:09 · 1703 阅读 · 0 评论 -
QPS,并发数计算
PV=page viewTPS=transactions per secondQPS=queries per secondRPS=requests per secondRPS=并发数/平均响应时间QPS = req/sec = 请求数/秒【QPS计算PV和机器的方式】QPS统计方式 [一般使用 http_load 进行统计]QPS = 总请求数 / ( 进程总数 * 请求时间 )QPS: 单个进程每秒请求服务器的成功次数服务器计算服务器数量 = ceil( 每天总PV / 单台服务器每原创 2020-08-04 18:19:05 · 5454 阅读 · 0 评论 -
volatile和内存屏障
文章目录什么是内存屏障?cpu高速缓存volatile什么是内存屏障?当多个线程访问同一个数据,内存屏障可以保证数据可见性和有序性。可以禁止指令重排序。因为cpu对内存的访问是乱序的,如果发生了指令重排序,可能会导致不同的结果。所以需要一个内存屏障,保证内存屏障前后的指令的有序性,可以确保屏障之前的读写操作,都提交到内存之后,再执行屏障后的读写操作从操作系统硬件的层面而言:cpu高速缓存线程是cpu调度的最小单元,cpu在处理运算时候,还需要与内存交互,比如读取内存数据,存储运算结果,这个IO是很原创 2021-06-02 03:00:32 · 2021 阅读 · 0 评论 -
关于Redis的二三事
关系型数据库1.以表格形式,基于行的数据存储,是一个二维模式2.存储的结构化的数据,数据存储有固定的模式,数据需要适应表结构表与表之间存在关联大部分关系型数据库都支持sql的操作,支持复杂的关联查询通过支持事务来提供严格的实时一致性redis 内存淘汰机制分布式锁 setNx限流 并发访问spring session内存计数秒杀...原创 2021-05-19 00:44:58 · 199 阅读 · 0 评论 -
Thread.sleep(0)的作用
Thread.sleep(0)的作用Thread.Sleep(0)作用,就是“触发操作系统立刻重新进行一次CPU竞争”。竞争的结果也许是当前线程仍然获得CPU控制权,也许会换成别的线程获得CPU控制权。这也是我们在大循环里面经常会写一句Thread.Sleep(0) ,因为这样就给了其他线程比如Paint线程获得CPU控制权的权力,这样界面就不会假死在那里。关于sleep()方法和yield()方法的区别如下。sleep()方法暂停 当前线程后,会给其他线程执行机会,不会理会其他线程的优先级:但yi原创 2021-03-18 17:23:27 · 5082 阅读 · 2 评论 -
线程池中的线程是如何超时自动销毁的?
worker 线程会从阻塞队列中获取需要执行的任务,这个方法不是简单的 take 数据,我们来分析下他的源码实现你也许好奇是怎样判断线程有多久没有活动了,是不是以为线程池会启动一个监控线程,专门监控哪个线程正在偷懒?想太多,其实只是在线程从工作队列 poll 任务时,加上了超时限制,如果线程在 keepAliveTime 的时间内 poll 不到任务,那我就认为这条线程没事做,可以干掉了 private Runnable getTask() { boolean timedOut原创 2021-03-17 17:01:27 · 2752 阅读 · 0 评论 -
原子操作类
由于变量类型的关系,在J.U.C中提供了12个原子操作的类。这12个类可以分为四大类原子更新基本类型AtomicBoolean、AtomicInteger、AtomicLong原子更新数组AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray原子更新引用AtomicReference、AtomicReferenceFieldUpdater、AtomicMarkableReference(更新带有标记位的引用类型)原子更新字段Atomic原创 2021-03-16 17:14:10 · 172 阅读 · 0 评论 -
interrupt(),interrupted,isInterrupted的区别
1、interrupt()interrupt() 方法用于中断线程,调用该方法的线程原创 2020-09-04 14:54:57 · 358 阅读 · 0 评论 -
限流——漏桶算法和令牌桶算法的区别
限流在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流缓存:缓存的目的是提升系统访问速度和增大系统处理能力降级:当服务流量剧增,影响到核心流程的性能,需要暂时屏蔽掉一些功能,待高峰过去或问题解决后再重新打开,以此释放服务器资源以保证核心任务的正常运行。限流:限流的目的是通过对并发访问或请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务、或排队或等待、降级等处理常用的限流算法有令牌桶和,漏桶,滑动窗口漏桶算法漏桶(Leaky Bucket) 算原创 2020-09-02 18:08:20 · 10337 阅读 · 3 评论 -
Semaphore的使用并实现的限流器
semaphore 基本原理semaphore 翻译成字面意思是信号量,Semaphore可以控制同时访问的线程个数,通过acquire()获取一个许可,如果没有就等待,而release()释放一个许可。从功能看semaphore的底层是基于AQS实现的一个共享锁,需要多个现场共享一个令牌池。创建semaphore实例的时候,需要一个参数permits,这个基本可以确定是设置给AQS的state的,然后每一个线程调用的acquire的时候,执行state = state-1,release的时候执行s原创 2020-09-01 16:48:25 · 276 阅读 · 0 评论 -
CountDownLatch和CyclicBarrier
countDownLatch是一个同步工具类,允许一个线程或者多个线程同时等待,直到其他线程的操作完毕再执行。coutDownLatch提供了2个方法,一个是countDown,一个是await,countDownlatch初始化的时候,会传入一个整数,赋值给内部计数器state,调用await方法会阻塞当前线程,并将当前线程加入到等到队列中,直到state等于0或者当前线程被中断,调用countDown方法,会使state的值减一,如果state等于0则唤醒等待队列中的线程。适应场景:1、场景一:在原创 2020-08-31 18:12:58 · 189 阅读 · 0 评论 -
HashMap1.7和1.8实现原理和区别
JDK1.7中的HashMapJDK1.7中的HashMap是一个数据与链表的结合体。底层是一个数组结构,数组中的每一项都是一个链表,当新建一个HashMap的时候,就会初始化一个数组。结构大致如下hashmap的成员变量1.DEFAULT_INITIAL_CAPACITY = 1 << 4;:初始桶(数组)大小为16,因为底层是数组,所以也是数组大小2.MAXIMUM_CAPACITY = 1 << 30:桶最大值,2的30次方3.DEFAULT_LOAD_FACTO原创 2020-08-28 17:09:33 · 2963 阅读 · 0 评论 -
wait/notify,notifyAll
wait之后,持有对象锁的线程 A会释放当前锁,释放 cpu 资源进入waiting状态.notify :表示持有对象锁的线程A 会释放当前锁,通知JVM唤醒某个竞争改对象锁线程的线程X,线程A的Synchronized代码块执行完并释放了锁之后,线程X获得对象锁的权限,其他竞争线程继续等待。(即使线程X执行完毕,释放了对象锁,其他竞争线程仍然等待,直至有新的notify或者notify...原创 2019-12-02 17:23:54 · 182 阅读 · 0 评论 -
condition实现生产者和消费者
生产者import java.util.concurrent.atomic.AtomicInteger;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;public class ConditionProducer implements Runnable { private Lock lock; private Condition condition; p原创 2020-08-25 16:58:50 · 1220 阅读 · 0 评论