关于分布式锁到底是个什么东西,我在这里就不多说了。
本文的分布式锁主要的构成元素有:ip,线程id,加锁次数。
ip:在集群环境下,部署在不同机器上的应用可能争抢一把锁,用ip实现互斥;
线程id:同一个应用下,不同的线程也可能争抢一把锁;
加锁次数:让锁对同一个线程是可重入的。每加一次锁,当前加锁次数加一,每释放一次锁,当前加锁次数减一。当加锁次数为0时,锁完全释放。
1、普通锁
1.1 单线程加锁解锁
//testlock为存在redis中的key,这个key存在表示,锁存在
LockUtil lock = new LockUtil("testlock");
System.out.println(lock.getLockInfo());//null
lock.tryLock();
System.out.println(lock.getLockInfo());//{"ip":"169.254.43.193","threadId":"1","count":1}
lock.unLock();
System.out.println(lock.getLockInfo());//null
1.2 多个线程抢锁
让多个线程抢锁,抢到锁的线程休息2秒,然后释放锁。
理论上,只有一个线程获取到锁。
for(int i=1;i<=5;i++) {
Thread t= new Thread(new Runnable() {
@Override
public void run() {
LockUtil lock = new LockUtil("testlock");
if(lock.tryLock()) {
System.out.println(System.currentTimeMillis()+"线程"+Thread.currentThread().getId()+",获取锁成功");
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.unLock();
System.out.println(System.currentTimeMillis()+"线程"+Thread.currentThread().getId()+",释放锁");
}else {
System.out.println(System.currentTimeMillis()+"线程"+Thread.currentThread().getId()+",获取锁失败");
}
}
});
t.start();
}
这里是打印结果,符合预期。
11563623233705线程13,获取锁失败
1563623233705线程11,获取锁失败
1563623233705线程14,获取锁失败
1563623233705线程15,获取锁失败
1563623233706线程12,获取锁成功
1563623235722线程12,释放锁
2、超时锁
2.1 多个线程抢锁
设置抢锁超时时间为3秒,抢到锁的沉睡2秒。
理论上,只有两个线程抢到锁,抢到锁的时间间隔为2秒,其他线程超时。
for(int i=1;i<=5;i++) {
Thread t= new Thread(new Runnable() {
@Override
public void run() {
LockUtil lock = new LockUtil("testlock");
if(lock.tryLock(3)) {
//设置超时时间为3秒
System.out.println(System.currentTimeMillis()+"线程"+Thread.currentThread().getId()+",获取锁成功");
try {
Thread.currentThread().sleep(2000);