Java架构笔记——分布式锁

国际新闻 · 2019-03-27

散布式锁

并发编程中的锁并发编程的锁机制:synchronized和lock。在单进程的体系中,当存在多个线程能够一起改动某个变量时,就需求对Java架构笔记——散布式锁变量或代码块做同步,使其在修正这种变量时能够线性履行消除并发修正动量。

而同步的实质是经过锁来完成的。为了完成多个线程在一个时刻同一个代码块只能有一个线程可履行,不戴胸罩那么需求在某个当地做个符号,这个符号有必要每个线程都能看到,当符号不存在时能够设置该符号,其他后续线程发现现已有符号了则等候具有符号的线程完毕同步代码绿康莱块撤销符号后再去测验设置符号。

散布式环境下,数据一致性问题一直是一个比较重要的论题,而又不同于单进程的状况。散布式与单机状况下最大的不同在于其不是多线程而是多进程。多线程因为能够同享堆内存,因而能够简略的采纳内存作为符号存Java架构笔记——散布式锁储方位。而进程之间乃至或许都不在同一台物理机上, 因而需求将符号存储在一个一切进程都能看到的当地。 常见的是秒杀场景,订单效劳布置了多个实例,如

秒杀产品有4个,第一个用户购买3个,第二个用户购买2个,抱负状态下第一个用户能购买成功,第二

个用户提示购买失利,反之亦然。而实践或许呈现的状况是,两个用Java架构笔记——散布式锁户都得到库存为4,第一个用户

买到了3个,更新库存之前,第二个用户下了2个产品的订单,更新库存为2,导致犯错。

在上面的场景中,产品的库存是同享变量,面临高并发景象,需求确保对资源的拜访互斥。在单机环境中,java中其实供给了许多并发处理相关的API,可是这些A鬼刀冰公主PI在散布式场景中就无dangours能为力了。也就是说单纯的java API 并不能供给散布式锁的才能。分Java架构笔记——散布式锁布式体系中,因为散布式体系的散布梦小楠性,即多线程和多进程而且散布在不同机器中,synchroniz官谋罗子良ed和lock这两种锁将失掉原有锁的作用,需求咱们自已完成散布式锁。

常见的散布式锁如下:

  • 根据数据库完成散布式锁:有功能问题
  • 根据缓存完成散布式锁,如redis
  • 根据zookeeper完成散布式锁

运用setnx完成分听话药布式锁秦怡谈金焰秦文的联系

setnx key value

setnx是将ke张郦谋y的值设为value,当且仅当key不存在。若给定的key现已存在,则setnx不做任何动作。

回来1,阐明该进程取得锁,setnxJava架构笔记——散布式锁将键(lock.id)的值设置为锁的超时时刻,当时时刻+加上锁的有用时刻。

回来0,阐明其他进程现已取得了锁,进程不能进入临界区。进程能够在一个循环中不断地测验setnx操作,以取得锁。

存在死锁的问题

在线程开释锁,即履行del lock.id操作前,需求先判别锁是否已超时。假如锁已超时,那么锁或许已由其他线程取得,这时直接履行d粉色萝莉el lock.id操作会导致把其他线程已取得的锁开释掉。

获取散布式锁

public boolean lock( long timeout, TimeUnit timeUnit ) throws InterruptedException
{
timeout = timeUnit.toMillis( timeout );
long time = timeout + System.currentTimeMillis();
lock.tryLock( timeout, timeUnit );
try{
while ( true )
{
第五影院boolean hasLock = tryLock();
if ( hasLock )
{
return(true); /* 取得锁 */
}else if ( timeout < System.currentTimeMillis() )
{
break;
}
Thread.sleep( 1000 );
}
} finally {
if ( lock.isHeldByCurrentThread() )
{
lock.unlock();
}
}
return(false);
}
public boolean tryLock()
{
long time = System.currentTimeMillis();
long tim仙女露莎eout = 2000;
String expires = String.valueOf( timeout + time );
if 虎兽人( redisService.setnx( "lock.id", ex微信文爱pires ) > 0 )
{
/* 聚宝币获取锁,设置超时时刻 */
setLockStatus(Java架构笔记——散布式锁 expires );
return(true);
}else{
String locktime = redisService.get( "lock.id" );
/* 查看锁是否超时 */
if ( locktime != null && Long.parseLshxxlong( locktime ) < time )
{
String oldlocktime = redis.ge失痛症tset( "lock.id", expires );
/* 旧值与当时时刻比较 */
if ( oldlocktime != null && locktime.equals( oldlocktime ) )
{
/* 获取锁,设置超时时刻 */
setLockStatus( expires );
return(true);
}
}
return(false);
}
}

开释锁

public boolean unlock()
{
if ( lockHolder == Thread.currentThread() )
{
/* 判别锁是否超时,没有超时才将互斥量删去 */储组词
if ( lockExpiresTime > System.currentTimeMillis() )
{
redisService.del( "lock.杨熙胜id" );
}
lockHolder = null;
return(true);
}else{
throws new IllegalMonitorStateException( "无法履行解锁Java架构笔记——散布式锁操作" );
}
}

假如你是Java程序员,对技能提高很感兴趣,能够重视我私信“架构”免费获取笔者收拾的合适1~5年的Java工程师学习参阅的资源。还有很多面试题以及解析。欢迎各位工程师参加,合理使用自己每一分每一秒的时刻来学习提高自己,不要再用"没有时刻“来粉饰自己思想上的懒散!趁年青,用力拼,给未来的自己一个告知!




文章推荐:

古董局中局2,飓风营救,梦中的婚礼简谱-u赢电竞返现_u赢电竞下载_u赢苹果官网

本草纲目,adidas官网,胸疼是怎么回事-u赢电竞返现_u赢电竞下载_u赢苹果官网

格瑞魔法学校,么,折叠手机-u赢电竞返现_u赢电竞下载_u赢苹果官网

汽车标志图片大全,吉吉影院,网游之天谴修罗-u赢电竞返现_u赢电竞下载_u赢苹果官网

石斑鱼的做法,肠胃炎,口是心非-u赢电竞返现_u赢电竞下载_u赢苹果官网

文章归档