系列文章目录
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:在工作中使用到redis,摸鱼中学习,redission
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 系列文章目录
- 前言
- 一、Redisson配置
- 二、lock()和tryLock()的区别
- 1. lock()
- 1). lock() 总结
- 2. tryLock()方法
- 1). lock.tryLock() 总结
- 总结
前言
提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
提示:以下是本篇文章正文内容,下面案例可供参考
一、Redisson配置
示例:在Springboot配置
二、lock()和tryLock()的区别
代码借用 链接: Redission实现分布式锁lock()和tryLock()方法的区别
1. lock()
自己占用锁30秒,如果业务在30内处理完,释放锁;如果业务超过30秒,在30s会释放锁。
lock.lock(30, TimeUnit.SECONDS); // 尝试在30秒内获取锁,如果获取不到则放弃
代码如下(示例): 任务需要20s
public String RedissonLock2() {
RLock lock = redissonClient.getLock("order_lock");
boolean success = true;
try {
System.out.println(Thread.currentThread().getName()+"获取锁前的时间:"+LocalDateTime.now());
// 尝试在30秒内获取锁(等待获取锁30秒)
lock.lock(30, TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()+"获取锁后的时间:"+LocalDateTime.now());
// 模拟业务处理耗时
System.out.println(Thread.currentThread().getName() + "模拟业务处理耗时20s:"+LocalDateTime.now());
// TimeUnit.SECONDS.sleep(3);
// 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
TimeUnit.SECONDS.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 判断当前线程是否持有锁
if (success && lock.isHeldByCurrentThread()) {
//释放当前锁
lock.unlock();
System.out.println(Thread.currentThread().getName() + "释放锁"+ LocalDateTime.now());
}
}
return "";
}
运行图:
第二次是堵塞的;
上述代码:如果第一次请求:获取锁时间为10s、业务处理需要20s ; 第二次请求:获取锁时间为10s、业务处理需要20s ;
// 第一次部分代码修改--其他不变.....
lock.lock(10, TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()+"获取锁后的时间:"+LocalDateTime.now());
// 模拟业务处理耗时
System.out.println(Thread.currentThread().getName() + "模拟业务处理耗时20s:"+LocalDateTime.now());
// TimeUnit.SECONDS.sleep(3);
// 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
TimeUnit.SECONDS.sleep(20);
//.....
// 第一次部分代码修改--其他不变.....
lock.lock(30, TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName()+"获取锁后的时间:"+LocalDateTime.now());
// 模拟业务处理耗时
System.out.println(Thread.currentThread().getName() + "模拟业务处理耗时20s:"+LocalDateTime.now());
// TimeUnit.SECONDS.sleep(3);
// 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
TimeUnit.SECONDS.sleep(20);
//.....
运行图:
第一次获取锁10s,业务结束耗时20s,由于业务超时锁在10s结束,第二个堵塞10s,获取锁持有时间30s,业务处理20s,20s后正常释放锁。
如果上述代码;第一次请求:获取锁时间为30s、业务处理需要20s ; 第二次请求:获取锁时间为10s、业务处理需要20s 。
第一次获取锁30s,业务结束耗时20s,由于业务完成锁在20s释放,第二个堵塞20s,获取锁持有时间10s,业务结束耗时20s,由于业务超时锁在10s结束
1). lock() 总结
使用 lock()
,会出现堵塞,在 lock.lock(30, TimeUnit.SECONDS)
获取时间内等待其他线程释放才能执行。lock() 方法
是阻塞获取锁的方式,如果当前锁被其他线程持有,则当前线程会一直阻塞等待获取锁,直到获取到锁或者发生超时或中断等情况才会结束等待。
2. tryLock()方法
当锁被其他占有时,等待5尝试获取锁,如果5s内获取不到,会立即废弃返回
false
;如果获取持有30s
//尝试获取锁,等待5秒,持有锁10秒钟
boolean success = lock.tryLock(5, 10, TimeUnit.SECONDS);
success = lock.tryLock(5,TimeUnit.SECONDS); // 尝试获取锁,等待5秒
代码如下(示例):
public String RedissonLock1() {
RLock lock = redissonClient.getLock("order_lock");
boolean success = true;
try {
System.out.println(Thread.currentThread().getName() + "获取锁前的时间:"+LocalDateTime.now());
// 尝试获取锁,等待5秒,持有锁30秒钟
success = lock.tryLock(5, 30, TimeUnit.SECONDS);
// lock.lock(0, TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName() + "获取锁后的时间:"+LocalDateTime.now());
if (success) {
System.out.println(Thread.currentThread().getName() + "获取到锁"+ LocalDateTime.now());
// 模拟业务处理耗时
// TimeUnit.SECONDS.sleep(3);
// 模拟业务处理耗时 大于锁过期,可能导致非自己持有的锁被释放。
System.out.println(Thread.currentThread().getName() +"模拟业务处理耗时20s:"+ LocalDateTime.now());
TimeUnit.SECONDS.sleep(20);
} else {
System.out.println(Thread.currentThread().getName() + "未能获取到锁,已放弃尝试");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
// 判断当前线程是否持有锁
if (success && lock.isHeldByCurrentThread()) {
//释放当前锁
lock.unlock();
System.out.println(Thread.currentThread().getName() + "释放锁"+ LocalDateTime.now());
}
}
return "";
}
运行结果图:
锁被占用时,第二次会尝试获取锁,在5s获取不到,立即放弃,业务不执行;
如果上述代码;第一次请求:等待5s、获取锁时间为30s、业务处理需要20s ; 第二次请求:获取锁时间为25s、获取锁时间为30s、业务处理需要20s 。
运行结果图:
第一次:开始请求,尝试5s获取锁,锁没有占用直接获取,不用等待5s,持有30s,业务执行20s;业务执行完还在持有时间内,释放锁在20s后。
第二次:开始请求,尝试在25s获取锁,25s内(开始请求时间不同,并非同时,并非在20s获取到锁)
,其他线程将锁释放或者中断,获取到锁,持有30s,第二次请求耗时总计total='业务处理耗时' + '尝试获取锁耗时'
1). lock.tryLock() 总结
使用 lock()
,会出现堵塞,而tryLock() 方法是一种非阻塞获取锁的方式,在尝试获取锁时不会阻塞当前线程,而是立即返回获取锁的结果,如果获取成功则返回 true,否则返回 false。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。