Мое приложение должно поддерживать журнал запросов на определенный ресурс, а несколько потоков будут записывать записи журнала. Единственная соответствующая информация - это метка времени запроса, и полученная статистика будет равна количеству запросов за последние X секунд. Метод, который возвращает статистику за определенное количество секунд, также должен поддерживать несколько потоков.Безопасность потока при многопоточном доступе к LinkedList
Я думал о приближении обработки параллелизма с использованием рамки Locks, с которой я не самый знакомый, следовательно, этот вопрос. Вот мой код:
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
. - Вместо этого следует использовать ReentrantReadWriteLock?
Просто знать, почему вы просто не используете public 'List Collections.synchronizedList (Список )), чтобы получить список, защищенный потоком? –
Jack
ли это устранит необходимость в замках? – amphibient
Java.util.concurrent.ConcurrentLinkedDeque является потокобезопасным со слабо согласованным итератором. – assylias