synchronized锁只能解决单个进程下多线程问题,而针对多个进程(比如多个用户参与秒杀)的情况,是无法解决的,所以需要依赖第三方独立中间件来实现分布式锁。zookeeper是负责分布式协调,所以可以实现分布式锁。
依赖zookeeper特性实现分布式锁:
- 同目录下节点唯一:可以依赖zookeeper的特性之一:同一节点下只能创建一个名字相同的节点;那么创建节点成功的客户端就抢占到了锁,没有创建成功的客户端就没有竞争到锁。但是会有惊群效应问题,一个客户端释放了锁,其他所有客户端都会再次去竞争,然而只有一个客户端可以竞争到锁,浪费性能。
- 临时有序节点:针对惊群效应问题,可以采用zookeeper另一个特性,在同一节点下创建临时有序节点,哪个客户端创建的节点序号最小,则代表抢占到锁;抢占到锁的客户端释放了锁,会从其他客户端中筛选出序号最小的那个去获取锁,根据节点序号顺序获取锁。
Curator实现分布式锁
// 基于临时有序节点实现分布式锁
InterProcessMutex lock = new InterProcessMutex(curatorFramework, "/lock");
try {
lock.acquire(); //抢占分布式锁资源,阻塞方法
// 需要分布式锁的业务代码
Order order = orderServie.getOne(orderId);
order.setStock(order.getStock - 1);
orderService.update(order);
}
|