
并发
文章平均质量分 92
Mutou_ren
这个作者很懒,什么都没留下…
展开
-
synchronized和lock保证的可见性
synchronized在进入时要读取主存,退出时刷新主存。但不会禁止重排序,只会保证锁内和锁外的排序不会乱,因此只能保证刚进入时数据是最新的原创 2020-07-24 09:45:33 · 1650 阅读 · 0 评论 -
volatile修饰List能否保证内部元素的可见性?
实验一:ArrayList多线程下的可见性代码 private static List<Integer> list; static { list = new ArrayList<Integer>(20); list.add(0); } public static void main(String[] args) throws InterruptedException { CountDownLatch l原创 2020-07-23 10:30:51 · 3640 阅读 · 2 评论 -
synchronized加锁对象有什么要求?
不同线程通过synchronized锁对象,要想让锁达到效果,必须保证多个线程锁住的是同一个对象。不要锁包装类:自动装箱使用的是valueOf方法,若没有缓存则会new一个包装对象,所以拿到的是不同对象,无法实现锁。不要锁参数对象,SpringMVC在参数绑定时生成的参数对象是独立的锁String字段时,要使用String.intern()返回的。该方法返回的是指向常量池的对象指针,可以保证是同一个。对于StringString s1 = new String("jwb")//堆String原创 2020-07-24 09:47:55 · 1229 阅读 · 0 评论 -
记一次锁和事物导致的并发问题
需求背景对系统内的物品做一个SN码追踪,我这边的设计是入库和出库操作都会将物品的SN码和相关单据信息记录到一张表中,由于存在小零件的物品,一包几百个都是同一个SN码,所以这里牵扯到一个数量。表结构的核心字段如下字段类型SN码varchar操作单号varchar操作数量int库内余数int……并发问题由于属于日志表,因此这张表的操作只...原创 2020-02-20 16:58:02 · 308 阅读 · 0 评论 -
AQS的doAcquire和doRelease
上篇博客讲了tryAcquire和tryRelease,这篇来看看AQS自身实现的doAcquire和doReleaseacquire独占锁AQS自身没有提供对doAcquireInterruptibly和doAcquireNanos的调用,交由子类使用,这俩都将同步队列节点入队操作放在了自己的方法内,而AQS自身对acquireQueued的实现acquire将这个操作从do方法中移了出来...原创 2020-01-07 22:45:21 · 328 阅读 · 0 评论 -
AQS的非公平锁与同步队列的FIFO冲突吗?
公平锁与非公平锁的含义都很明白,公平锁必须排队获取锁,锁的获取顺序完全根据排队顺序而来,而非公平就是谁抢到是谁的。我们都知道AQS中的锁获取,如果首次获取失败会进入到内部的同步队列中阻塞等待,只有前面的节点唤醒当前节点才能去尝试获取锁从我之前的博客内容可知,锁获取的核心,实际上是在try方法中定义的,在节点从阻塞中醒来时,都会用try方法来获取锁,而公平与否在try方法中体现,即在公平锁中,t...原创 2020-01-07 22:44:49 · 1681 阅读 · 19 评论 -
AQS子类的tryAcquire和tryRelease的实现
思想AQS通过一个private volatile int state;来表示锁的状态,当state=0时代表无锁,>0代表有锁,>1代表重入次数AQS从AOS继承了private transient Thread exclusiveOwnerThread;用来记录当前持有独占锁的线程暴露方法// 尝试获取 独占锁protected boolean tryAcquire(in...原创 2020-01-07 19:50:43 · 1787 阅读 · 0 评论 -
Redis分布式锁中的问题
使用使用set key value ex 5 nx命令设置key value 5秒过期 不存在才能设置成功,成功代表获取了分布式锁随机值在set时,key为固定,但value对不同线程应不同,如使用线程名。如果使用的value相同会有什么问题?我们假设固定为key=lock_key,value=lock_value假设线程1获取到了分布式锁,超时30秒,但线程1的实际执行实际达到了40秒...原创 2020-01-05 19:33:18 · 221 阅读 · 0 评论 -
Redis缓存问题及解决方案
查询流程:【问题1】——穿透、击穿及雪崩问题描述线程T1在查DB并更新redis缓存的过程中(还未成功将结果放入缓存),有大量并发请求对该Key请求,导致有大量的线程去走查DB并更新redis缓存的流程,不仅对DB造成巨大压力,同时还会产生多次不必要的redis缓存更新操作(网络开销)问题原因没有对某些可能的热点数据进行预热缓存过期导致【缓存击穿】 或者【缓存雪崩】对同一个不存在...原创 2020-01-05 17:09:30 · 345 阅读 · 0 评论 -
Semaphore实现原理
示例代码public class TestSemaphore { public static Semaphore semaphore=new Semaphore(2); public static void main(String[] args) { System.out.println("main start"); for (int i =0...原创 2020-01-04 14:42:16 · 208 阅读 · 0 评论 -
CyclicBarrier的实现原理
示例代码public class TestCyclicBarrier { public static CyclicBarrier barrier = new CyclicBarrier(4,()-> { System.out.println(Thread.currentThread().getName()+"dododo"); try { ...原创 2020-01-04 14:00:31 · 189 阅读 · 0 评论 -
基于AQS分析CountDownLatch的原理
示例代码先贴一段示例代码public class TestCountDownLatch { public static CountDownLatch countDownLatch = new CountDownLatch(3); public static void main(String[] args) throws InterruptedException { ...原创 2020-01-03 21:54:08 · 257 阅读 · 0 评论 -
synchronize和Lock区别
以前一直说synchronize是一种重量级锁,因为以前synchronize是没有锁升级这个机制的,多个线程竞争锁时没有拿到锁的会直接进入阻塞状态,而后来引入了锁升级后,synchronize便没那么重了,具体可参加我的另一篇文章synchronizesynchronize的加锁是在对象头进行操作的,而Lock是基于AQS中的state进行的,每次进入锁就会使state+1,而在基于AQS的L...原创 2019-12-29 11:54:09 · 220 阅读 · 0 评论 -
基于AQS分析Condition
对于Object的wait和notify方法我们已经很熟悉了,同时也知道与之相似的Condition接口,具体用法这里不讲,我们基于上一篇AQS的介绍来讲讲Condition的实现原理等待队列Condition的实现类ConditionObject是AQS的内部类,其实现是需要获取Lock相关的锁,且实现方式也与AQS很相似我们知道在AQS中存在一个同步队列,当线程没有获取到锁时,同步器会将...原创 2019-12-28 21:26:15 · 372 阅读 · 0 评论 -
0代码讲解Java中AQS的实现原理
我们知道Java中的锁有Synchronize和Lock,而Lock是基于队列同步器AQS(AbstractQueuedSynchronizer)实现的,今天来分析一下到底什么是AQS这里不贴代码,只讲思想原理,代码其实很简单,原理理解了,翻翻源码就知道了什么是锁?首先明确一下什么是锁,所谓锁,无非就是一个独一份的共享资源,多个线程去抢这个资源,谁拿到了这个共享资源谁就持有了锁。表现在代码...原创 2019-12-28 11:32:43 · 301 阅读 · 2 评论 -
Java中的偏向锁、轻量级锁、重量级锁以及锁升级
什么是锁?Java中的锁的状态有四种:无锁、偏向锁、轻量级锁、重量级锁,状态会随竞争状态改变,低等级的锁可以升级为高等级的锁,即锁升级;但反之不行,没有锁降级。要理解锁升级,首先要了解一些基本概念:加锁行为到底锁的是什么?加锁记录存在哪里?我们以Java最常见的synchronized为例首先要理解,锁是一种排他状态,是一种竞争性的共享资源,谁拿到了这个共享资源,谁就持有了锁。如基于...原创 2019-12-14 15:47:51 · 341 阅读 · 0 评论 -
Java中的并发工具及框架
并发工具类CountDownLatch允许一个或多个线程等待其他线程完成操作,比传统的join机制更好。其构造函数接收一个int类型的参数作为计数器(初始化后无法改变该值),即要等待的线程数量(也可以是一个线程的多个执行步骤)。每次调用countDown都会使计数器减一,await()方法会一直阻塞当前线程知道计数器归零,同时该方法也提供超时机制。CyclicBarrier同步屏障所有线...原创 2018-12-20 20:24:29 · 455 阅读 · 0 评论 -
Java中的线程
Runnable接口定义了任务,但若想实现线程行为,必须将任务附着在线程上,因此创建线程Thread并将一个Runnable对象交给该线程,启动thread的start对象将为该线程执行必须的初始化操作,并调用Runnable对象的run方法执行任务。...原创 2018-12-20 20:34:14 · 136 阅读 · 0 评论 -
高并发项目总结
功能实现两次MD5加密密码第一次MD5Http是明文传输,为了不泄露密码,用户在前端表单输入时,在前端对密钥做第一次MD5处理,发送给后端。第二次MD5后端收到密码后做第二次MD5处理,并存入数据库中。这是防止数据库泄露根据彩虹表反向推到出用户密钥。为了增强密码安全,增加随机盐值混淆密码JSR303参数校验对VO层对象的属性设定限制,如格式、非空等,无需在每个方法里重复判断。...原创 2019-01-27 16:14:13 · 1398 阅读 · 0 评论 -
自己写阻塞队列实现消费者与生产者
阻塞队列的特点就是:若队列内无元素,get操作会进入阻塞状态若队列已满,set操作会进入阻塞状态JDK中提供了七种阻塞队列供我们使用,搞明白了原理后自己手写一个简易版的阻塞队列。public class MyBlockingQueue { private LinkedList<Integer> objects=new LinkedList<Integer>...原创 2019-05-24 13:33:34 · 305 阅读 · 0 评论 -
Java中的锁及等待通知机制
synchronizedsynchronized是一种重量级锁,表现形式有三种对于普通同步方法,锁是当前的实例对象对于静态同步方法,锁是类的Class对象对于同步方法块,锁是synchronized括号里配置的对象每个对象都有一个minitor与之关联,当一个minitor被持有后,它将处于锁定状态,synchronized的实现原理即是基于进入Minitor对象来实现方法同步和代码...原创 2018-12-17 22:41:34 · 1541 阅读 · 0 评论