说明
这一节讲解存放消息时涉及到的锁
PutMessageLock :锁的接口
PutMessageReentrantLock:可重入锁的实现
PutMessageSpinLock: 自旋锁的实现
源码很简单直接贴
源码
接口PutMessageLock
public interface PutMessageLock {
void lock();
void unlock();
}
重入实现PutMessageReentrantLock
public class PutMessageReentrantLock implements PutMessageLock {
private ReentrantLock putMessageNormalLock = new ReentrantLock(); // NonfairSync
@Override
public void lock() {
putMessageNormalLock.lock();
}
@Override
public void unlock() {
putMessageNormalLock.unlock();
}
}
自旋实现PutMessageSpinLock
public class PutMessageSpinLock implements PutMessageLock {
//true: Can lock, false : in lock.
private AtomicBoolean putMessageSpinLock = new AtomicBoolean(true);
@Override
public void lock() {
boolean flag;
do {
flag = this.putMessageSpinLock.compareAndSet(true, false);
}
while (!flag);
}
@Override
public void unlock() {
this.putMessageSpinLock.compareAndSet(false, true);
}
}
思考
为什么存放消息需要锁,而MappedFile中shutdown却不需要锁
MappedFile中对改变内容的只有追加新内容,不会修改内容或者删除内容,互斥的是存放消息即可
而对于shutdown, ReferenceResource#shutdown执行了之后会导致ReferenceResource#hold返回false
使得不会有后续的MappedFile中的selectMappedBuffer,commit,flush的行为发生
即在代码控制了shutdown之前的操作都有效,之后的操作均无效
重入锁和自旋锁的区别
网上资料很多,简单来说,自旋锁不能先锁两次再释放两次,而重入锁可以
网友评论