我正在尝试通过两个调用创建一个不公平的缓冲区
为缓冲区增加价值
清空缓冲区
清空队列的线程应具有更高的优先级,而添加到队列的线程应具有更高的优先级。
如果缓冲区已满,我会在内部调用empty方法以允许队列为空。
基本思想是,添加缓冲区上的锁仅限于addTimeout,而empty的锁为emptyAddRatio * addTimeout,因此add将具有更高的优先级(假设我有更多的添加,然后为空)。
public class EmptyPriorityBuffer {
private ReentrantLock lock = new ReentrantLock(true);
private long addTimeout = 10;
private long emptyAddRatio = 5;
private int maxSize = 1000;
private LinkedBlockingDeque<Object> buffer = new LinkedBlockingDeque<>(maxSize);
public List<Object> empty() {
try {
lock.tryLock(addTimeout * emptyAddRatio, TimeUnit.MILLISECONDS);
ArrayList<Object> result = new ArrayList<>();
buffer.drainTo(result);
return result;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
return Collections.emptyList();
}
public void add(Object object) {
try {
lock.tryLock(addTimeout, TimeUnit.MILLISECONDS);
if (!buffer.offer(object)) {
empty();
buffer.offer(object);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
我的问题:
在缓冲区已满的情况下会发生什么。
当前使用addtimeout锁定的线程,现在它请求用emptyAddRatio * addTimeout嵌套的锁大于addTimeout。
在emptyAddRatio * addTimeout或addTimeout之后线程会被中断吗?
最佳答案
如果您已经拥有锁,那么在重入情况下的timeout参数将无效。也就是说,对add
的调用已经获取了锁(并且可能不得不等待最长addTimeout
毫秒。任何进一步的尝试获取同一锁的尝试都将立即成功。
但是请注意,您需要在方法lock.tryLock
和empty
中都检查add
的返回值,以确定获取锁是实际成功还是超时。在后一种情况下,您可能想要中止而不是继续。