并发编程
文章平均质量分 65
@来杯咖啡
物极必反,否极泰来,法天象地,以定位也.
展开
-
健壮的秒杀系统应该考虑哪些问题
这里写目录标题一:秒杀应该考虑哪些问题1.1:超卖问题解决方式1.2:高并发解决方式1.3:接口防刷解决方式1.4:秒杀url解决方式1.5:数据库设计解决方式1.6:大量请求问题参考链接:一:秒杀应该考虑哪些问题1.1:超卖问题分析秒杀的业务场景,最重要的有一点就是超卖问题,假如备货只有100个,但是最终超卖了200,一般来讲秒杀系统的价格都比较低,如果超卖将严重影响公司的财产利益,因此首当其冲的就是解决商品的超卖问题。解决方式项目肯定是集群部署,扣减库存的逻辑在一段代码中,那么给这段代码加锁。原创 2022-02-20 14:25:09 · 627 阅读 · 0 评论 -
对象头 - hashcode
hashcode对象头中的mark word存储对象运行时信息,如Hash Code、Age(对象的年龄)、锁状态标识、线程持有的锁、偏向线程ID、偏向时间戳等。知识准备:场景1 – 调用hashCode(),对象头才有hashCode值:public class Test { public static void main(String[] args) { A a = new A(); //jvm的信息 System.out.println原创 2021-03-24 18:00:45 · 971 阅读 · 1 评论 -
ReentrantLock【公平锁和非公平锁】的【加锁和解锁】全过程
声明:ReentrantLock的公平锁和非公平锁都是【独占锁】;加锁和解锁流程图原创 2021-03-24 15:11:56 · 251 阅读 · 1 评论 -
Java中的两大同步唤醒机制?(park和unpark、notify和wait)
Java中两大等待唤醒机制• 基于monitor机制的:Object类中的wait和notify方法。–synchronized• 基于线程的:LockSupport类中的park和unpark方法。–juc包下的unpark与notify最大的区别unpark可以指定唤醒哪个线程;notify是随机唤醒线程;park和unpark方法演示场景描述:程序一旦启动,当遇到 LockSupport.park();的时候会被阻塞;5s后,遇到 LockSupport.unpark(原创 2021-03-24 10:01:58 · 510 阅读 · 0 评论 -
假如你是“道格李”,你将如何设计Lock锁?
逻辑如下:ReentrantLock lock = new ReentrantLock(false);//false是非公平锁,true是公平锁T1,T2,T3三个线程要执行下面代码的逻辑;只有T1可以执行,那么T2和T3两个线程放哪??lock.lock() 1. T1获取锁成功,而T2和T3进入循环 while(true){ //当加锁失败不会立即释放cpu,而是进行CAS自旋,即:令线程入队成功,然后等待被唤醒,最后重新获取锁资源。 if(CAS获取锁成功){ /原创 2021-03-24 09:45:24 · 933 阅读 · 0 评论 -
synchronized锁优化
因为重量级锁总是在用户态和内核态之间转换,大大消耗性能。因此,jdk1.6之后对synchronized进行优化。自旋锁与自适应自旋共享数据的锁定状态只会持续很短的一段时间, 为了这段时间去挂起和恢复线程并不值得。 现在绝大多数的个人电脑和服务器都是多路(核) 处理器系统, 如果物理机器有一个以上的处理器或者处理器核心, 能让两个或以上的线程同时并行执行, 我们就可以让后面请求锁的那个线程“稍等一会”, 但不放弃处理器的执行时间, 看看持有锁的线程是否很快就会释放锁。 为了让线程等待, 我们只须让线程执原创 2021-03-11 17:47:06 · 482 阅读 · 1 评论 -
对象内存布局详解
对象内存布局详解声明64bit虚拟机和32bit虚拟机,对象所占内存是不一样的:64位jvm中Mark Word占64bit;32位jvm中Mark Word占32bit。根据是否开启元数据类型指针:如果开启- klass占8字节;如果不开启(默认不开启)- klass占4个字节一、对象内存布局1. 对象布局介绍HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。1.1 对原创 2021-03-11 17:00:52 · 1326 阅读 · 0 评论 -
理解Monitor监视器锁原理
理解Monitor监视器锁原理任何一个对象都有一个Monitor与之关联,当且一个Monitor被持有后,它将处于锁定状态。Synchronized在JVM里的实现都是 基于进入和退出Monitor对象来实现方法同步和代码块同步,虽然具体实现细节不一样,但是都可以通过成对的MonitorEnter和MonitorExit指令来实现。• monitorenter:每个对象都是一个监视器锁(monitor)。当monitor被占用时就会处于锁定状态,线程执行monitorenter指令时尝试获取monito原创 2021-03-11 15:45:48 · 5753 阅读 · 6 评论 -
synchronized底层原理
synchronized底层原理synchronized是基于JVM内置锁实现,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex lock(互斥锁)实现,它是一个重量级锁性能较低。当然,JVM内置锁在1.5之后版本做了重大的优化,如锁粗化(Lock Coarsening)、锁消除(Lock Elimination)、轻量级锁(Lightweight Locking)、偏向锁(Biased Locking)、适原创 2021-03-11 15:38:39 · 803 阅读 · 1 评论 -
字节码查看工具
查找Java字节码文件(严谨的说:其实是反编译字节码后的文件)的工具:• javap(jdk自带的,整合idea链接 - 显示出来的字节码比较简单);• jclasslib(下载插件,整合idea链接 -);• idea自带的-Bytecode Viewer,不用安装(推荐这个,显示的信息可读性最高)...原创 2021-03-11 15:06:43 · 591 阅读 · 0 评论 -
synchronized锁升级详细讲解案例:代码+流程图
声明:以下是JDK1.8的版本,1.8默认是开启偏向锁延迟的,时间大约4s;为什么默认4s才开启偏向锁?–jvm启动的时候,自己会创建十几个线程分别去初始化很多带有synchronized同步代码块的类。所有jvm启动的时候内部就存在线程的竞争,Java为了避免对象锁从偏向锁-轻量锁-重量锁的升级带来的开销;锁是针对“同步块”的,只有遇到“同步块”才会出现锁,这句话就解释了“无锁可偏向”的语义,因为没有遇到“代码块”,所以即使具备“偏向标识”也是无锁状态;1.无锁到偏向锁场景:JDK1.原创 2021-03-11 10:09:14 · 2229 阅读 · 0 评论 -
并发编程-缓存一致性协议中缓存行的“伪共享”问题
伪共享伪共享的定义如果多个核的线程在操作同一个缓存行中的不同变量数据,那么就会出现频繁的缓存失效,即使在代码层面看这两个线程操作的数据之间完全没有关系。这种不合理的资源竞争情况就是伪共享(False Sharing)Q:避免伪共享• 1.缓存行填充• 2.使用 @sun.misc.Contended 注解(java8)package thread;public class FalseSharingTest { public static void main(String[] args原创 2021-03-09 20:46:26 · 267 阅读 · 0 评论 -
并发编程-volatile为什么保证不了原子性?
举个栗子一个变量i被volatile修饰,两个线程想对这个变量修改,都对其进行自增操作也就是i++,i++的过程可以分为三步,首先获取i的值,其次对i的值进行加1,最后将得到的新值写会到缓存中。线程A首先得到了i的初始值100,但是还没来得及修改,就阻塞了,这时线程B开始了,它也得到了i的值,由于i的值未被修改,即使是被volatile修饰,主存的变量还没变化,那么线程B得到的值也是100,之后对其进行加1操作,得到101后,将新值写入到缓存中,再刷入主存中。因为volatile底层使用的是缓存一致性原创 2021-03-09 17:04:38 · 284 阅读 · 0 评论 -
并发编程-volatile的可见性
下面的代码,修改load函数中doSomething(0);传入的值,从0到4,分别会出现能跳出循环和不能跳出循环两种情况0,什么也不做,不能跳出循环1,sleep,能跳出循环2,使用System.out.println输出,能跳出循环3,等待10微秒,不能跳出循环4,等待20微秒,能跳出循环package thread;public class VisibilityTest { private boolean flag = true; public void refres原创 2021-03-09 11:09:06 · 116 阅读 · 0 评论