问题1.sychronized关键字/Lock为什么在项目里没用
这个问题的前提是要搞清楚三个名词:分布式、高并发、多线程
分布式
分布式是一种为了解决单个服务器容量和性能瓶颈问题而采用的优化方式。分布式领域要解决的问题也很多,比如:分布式文件系统、分布式缓存、分布式数据库、分布式计算等等。
Hadoop实现了一个分布式文件系统,Zookeeper是Hadoop的一个子项目,是一个分布式服务框架,MQ是消息队列都和分布式有关。
分布式的实现有两种形式:水平扩展、垂直拆分
高并发
高并发相对于分布式来说是通过分布式技术来解决问题,视频中用到优化高并发的手段有:页面缓存静态化以及CDN,分布式队列,防刷限流等
多线程
多线程旨在处理多个线程并发执行带来的线程安全问题,在Java多线程编程中,用到了synchronized,Lock锁以及原子类等等并发编程的知识,而这些是基于JVM层面上,单机系统下针对多个线程竞争共享资源的操作,但是在高并发、高流量的情况下就要用到分布式的系统,原有的synchronized/Lock锁会失效。
举个例子来说明这个问题:
一个订单下单的系统,部署订单的服务器有多个,库存的数据库也有多个,用户A和用户B同时进行下单,由于订单系统负载均衡策略,将A的下单交给系统1来处理,B的下单交给系统2去处理,此时系统1,2分别查询库存系统1和库存系统2,发现库存都充足,所以能够下单,这样会造成商品数量被扣减成负数的情况,也叫库存超卖
解决办法:
解决分布式下的并发问题有以下几种解决办法,大概就是无锁和有锁:
- 消息队列
采用消息队列就是避免分布式系统中加锁的操作,项目中秒杀下单的方法具体是:
在解决秒杀下单的问题时,是一个写热点问题,写操作都需要加锁以防并发写入数据库会有出错,而项目中将下单后的库存数据先写入到redis缓存中,避免直接将大量请求打到数据库上;为了保证redis缓存中库存数据和数据库的一致性,不发生超卖灾难