我的应用程序需要保留对特定资源的请求的访问日志,并且多个线程将记录日志条目。唯一相关的信息是请求的时间戳,检索的统计信息将是过去 X 秒内发生的请求数量。返回给定秒数的统计信息的方法还需要支持多线程。
我正在考虑使用以下方法来处理并发处理Locks http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/package-frame.html框架,我对此不是最熟悉,因此这个问题。这是我的代码:
import java.util.LinkedList;
import java.util.concurrent.locks.ReentrantLock;
public class ConcurrentRecordStats
{
private LinkedList<Long> recLog;
private final ReentrantLock lock = new ReentrantLock();
public LinkedConcurrentStats()
{
this.recLog = new LinkedList<Long>();
}
//this method will be utilized by multiple clients concurrently
public void addRecord(int wrkrID)
{
long crntTS = System.currentTimeMillis();
this.lock.lock();
this.recLog.addFirst(crntTS);
this.lock.unlock();
}
//this method will be utilized by multiple clients concurrently
public int getTrailingStats(int lastSecs)
{
long endTS = System.currentTimeMillis();
long bgnTS = endTS - (lastSecs * 1000);
int rslt = 0;
//acquire the lock only until we have read
//the first (latest) element in the list
this.lock.lock();
for(long crntRec : this.recLog)
{
//release the lock upon fetching the first element in the list
if(this.lock.isLocked())
{
this.lock.unlock();
}
if(crntRec > bgnTS)
{
rslt++;
}
else
{
break;
}
}
return rslt;
}
}
我的问题是:
- 这个会不会用
ReentrantLock
确保线程安全?
- 是否需要使用锁
getTrailingStats
?
- 我可以使用以下方法完成这一切吗
synchronized
块?我使用锁的原因是因为我想在 R 和 W 部分中使用相同的锁,以便一次在一个线程中完成列表中第一个元素(最近添加的条目)的写入和读取,并且我不能只用synchronized
.
- 我应该使用可重入读写锁 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html反而?
锁可能会成为主要的性能瓶颈。另一种方法是使用并发链接双端队列 http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentLinkedDeque.html: use offerFirst
添加新元素,并使用(弱一致)iterator
(这不会抛出ConcurrentModificationException
) 代替 for-each 循环。优点是这将比您的实现或比synchronizedList
实现,但缺点是迭代器是弱一致的 - 线程 1 可能会在线程 2 迭代列表时向列表中添加元素,这意味着线程 2 不会计算这些新元素。但是,这在功能上相当于让 thread2 锁定列表,以便 thread1 无法添加到列表中 - 无论哪种方式,thread2 都不会计算新元素。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)