并发
文章平均质量分 70
skyline_wx
这个作者很懒,什么都没留下…
展开
-
基于redis实现分布式锁的几种方式与问题
基于redis的分布式锁的演化与探究原创 2022-04-18 22:54:15 · 675 阅读 · 0 评论 -
如何解决应用系统数据库与缓存一致性问题
随着互联网应用的普及,内容信息越来越复杂,用户数和访问量越来越大,我们的应用需要支持更多的并发量,同时我们的应用服务与数据库服务器所做的计算也越来越多。但是我们的应用服务器的资源是有限的,很多时候性能的瓶颈会出现在各种IO上面。此时,就需要我们引入缓存机制,减少IO,减少计算,提高响应速度,优化用户体验。原创 2022-04-18 22:50:02 · 595 阅读 · 0 评论 -
ReentrantReadWriteLock使用场景思考及验证
ReentrantReadWriteLock使用场景思考CachedDataRWDictionary思考和验证最近一直在琢磨ReentrantReadWriteLock的使用场景是什么,后来突然就想明白了,其实就是读读并发、读写互斥、写写互斥而已。如果一个对象并发读的场景大于并发写的场景,那就可以使用ReentrantReadWriteLock来达到保证线程安全的前提下提高并发效率。首先,我们先了解一下Doug Lea为我们准备的两个demo。CachedData一个缓存对象的使用案例,缓存对象在使用原创 2021-11-21 21:34:07 · 2586 阅读 · 16 评论 -
并发编程:synchronized和lock有什么区别,什么时候用synchronized?什么时候用lock?
这个问题要从两个角度回答:非功能层面坊间传闻,从synchronized被优化后,效率略微高于lock,比较有利的证据是在1.8中ConcurrentHashMap处理同步时,直接使用了synchronized而不再使用lock。这个从某种程度上说明sun对自己的亲儿子还是比较认可的。功能层面lock支持tryLock、lockInterruptibly和超时获取锁,synchronized都不支持lock支持公平、非公平两种锁,但是synchronized只能是非公平使用lock时,必须手原创 2021-07-03 21:13:58 · 1001 阅读 · 0 评论 -
JMM之as if serial和happens-before原则
as if serial这句话的意思是,不管如何指令重排,在单线程下,程序的执行结果不会发生变化。public int method1(){ int a=0; int b=0; int x=a+b; return x;}以上面这段代码为例,指令重排之后,可能会先执行b=0再执行a=0,但是不管指令怎么重排,x=a+b一定会在ab被赋值之后。happens-before原则1程序次序规则在一个线程内,按照程序代码顺序,书写在前面的操作先行发生于书写在后面的操作。准确的说应该是控制流顺转载 2021-07-03 12:03:42 · 129 阅读 · 0 评论 -
JMM之指令重排以及案例分析
首先,我们先个下面的例子:@SpringBootTestclass DemoApplicationTests12 { private static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests12.class); int a = 0, b = 0; int x = 0, y = 0; /** * 指令重排 */ @Test public void原创 2021-07-02 07:52:16 · 510 阅读 · 0 评论 -
ScheduledExecutorService scheduleAtFixedRate、scheduleWithFixedDelay以及创建定时心跳
ScheduledExecutorService scheduleAtFixedRate、scheduleWithFixedDelay以及创建定时心跳scheduleAtFixedRatescheduleWithFixedDelay创建定时心跳scheduleAtFixedRatescheduleAtFixedRate按固定的周期调度,api如下public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,原创 2021-07-01 07:50:08 · 1361 阅读 · 0 评论 -
ThreadPoolExecutor 参数详解
我们看下ThreadPoolExecutor参数最多的构造器:public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Run原创 2021-06-29 08:34:30 · 683 阅读 · 1 评论 -
并发编程——手写一个简单的线程池
线程池在我们的开发中使用频率非常高,为了更好的理解线程池,我尝试手写了一个只能单线程提交任务的简易版线程池。private static final Logger logger = LoggerFactory.getLogger(DemoApplicationTests9.class);@Testpublic void test() { SkylinePool pool = new SkylinePool(2, 5,((taskQueue, task) -> { //阻原创 2021-06-25 11:05:01 · 153 阅读 · 0 评论 -
并发编程——CountDownLunch(闭锁)、CyclicBarrier(栅栏锁)、Semaphore(信号量)
这里写目录标题CountDownLunchCyclicBarrierSemaphoreCountDownLunchcountDownLunch,又叫闭锁。它有三个关键的api:new CountDownLatch(count); 创建一个闭锁,并声明count的值countDownLatch.await(); 如果countDownLunch的count不是0,则阻塞当前线程直到count等0countDownLatch.countDown();将countDownLunch中的count减一原创 2021-06-23 22:24:29 · 1322 阅读 · 0 评论 -
为什么ReentrantReadWriteLock不能锁升级
在ReentrantReadWriteLock中,锁是不可以升级的,只能降级。也就是如果当前线程持有了ReadLock,那么就不能再获取WriteLock,但是,如果当前线程持有了WriteLock,可以直接获取ReadLock下面用代码尝试一下:Logger logger = LoggerFactory.getLogger(this.getClass());ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteL原创 2021-06-15 11:07:45 · 1552 阅读 · 0 评论 -
ReentrantLock解锁原理
在上一篇文章中我们了解了ReentrantLock的加锁过程,今天我们来了解一下ReentrantLock的解锁过程。解锁时,我们需要调用unlock方法而这个unlock方法指向了java.util.concurrent.locks.AbstractQueuedSynchronizer#release这里面的逻辑很简单,首先尝试释放锁,如果成功,那就叫醒下一个等待者并返回true,如果不成功,那就返回false。首先,我们看下tryRelease方法:首先,如果一个线程没有持有锁,是不可以释原创 2021-06-06 23:46:01 · 157 阅读 · 0 评论 -
ReentrantLock加锁原理
今天来探究一下ReentrantLock中非公平锁的加锁原理,首先看一段代码来了解一下ReentrantLock是如何使用的ReentrantLock lock = new ReentrantLock();Logger logger = LoggerFactory.getLogger(this.getClass());Thread t1 = new Thread(() -> { logger.info("线程[{}]在[{}]开始尝试获取锁", Thread.currentThread().g原创 2021-06-05 23:02:17 · 271 阅读 · 0 评论 -
并发编程——GuardedObject
GuardedObject,意思就是被保护的对象,这个对象常见于线程间的数据通信,假如有如下的业务场景:线程t1负责处理业务数据,处理完成后,将结果设置到ResultObj中,这时,主线程从ResultObj中获取返回值,如果还没有返回值,那么主线程就先阻塞。上面图中的ResultObj就是GuardedObject接下来,我们开始设计GuardedObject,class GuardedObject{ private Object result; private final Object lo原创 2021-05-29 21:53:38 · 485 阅读 · 1 评论 -
并发编程——多个线程交替打印
并发编程原创 2021-05-28 22:41:29 · 626 阅读 · 0 评论 -
并发编程——公平锁与非公平锁
公平锁与非公平锁什么是公平锁和非公平锁?公平锁非公平锁总结synchronized是公平还是非公平锁?什么是公平锁和非公平锁?在并发编程中,我们经常会遇到锁,大家也都知道,锁分为公平锁和非公平锁,那么什么是公平锁,什么是非公平锁呢?我们常见的synchronized是公平锁还是非公平锁?公平锁所谓公平锁,是说在加锁时,需要需要判断当前是否有人排队,如果有人排队,那么自己就不去抢锁,而是进入队列,这里可以参考ReentrantLock中公平锁的加锁方式在FairSync的tryAcquire方法中原创 2021-05-24 22:12:12 · 186 阅读 · 0 评论 -
并发编程—锁
发生了系统调用的锁就是重量锁sync为什么是重量锁sync不一定是重量锁,只有当sync关键字是10时,底层会使用mutex,这时候,他才是重量锁mutex抢锁,抢不到会sleep,而ring3没有sleep的权限,这时候需要升级到ring0,这时就发生了用户态到内核态的变化,一旦发生了内核切换,就是重量锁了。内核态:运行操作系统程序,操作硬件用户态:运行用户程序自旋锁:1、操作系统层面pthread_spin2、reentrantlock 在jvm层面是自旋的,当高并发时,但是在os层面上原创 2021-05-13 18:07:26 · 255 阅读 · 0 评论 -
并发编程——线程的本质以及线程是如何被创建的
线程的本质开启一个JAVA线程底层原理开启一个JAVA线程在java中开启一个线程使用的是下面的方法。public class TestThreadStart { public static void main(String[] args) { Thread thread = new Thread(){ @Override public void run() { System.out.println("i am new Thread! from java "); }原创 2021-05-10 10:00:58 · 153 阅读 · 0 评论