我需要创建一个列表以执行以下操作:
下面是我要使用ArrayList实施的代码,该代码每秒钟保持一次就清除列表。
class myclass{
List persistList;
ScheduledExecutorService persistExecutor;
ScheduledFuture scheduledFuture;
PersistOperation persistOperation;
//Initialize delay, interval
void init(){
scheduledFuture=persistExecutor.scheduleAtFixedRate(new persistOperation(persistList), delay, interval, TimeUnit.SECONDS);
}
void execute(msg){
//process the message and add to the persist list
}
class PersistOperation implements Runnable{
List persistList
PersistOperation(List persistList){
//Parameterized constructor
}
run(){
//Copy persistList to new ArrayList and clear persistList
//entity manager persist/update/merge
}
}
}
答案 0 :(得分:1)
并继续以100或1000的批次从集合的另一端删除并保存到数据库中。
这是合理的,只要从集合中轮询多个线程即可。
下面是我要使用ArrayList实现的代码
在这里ArrayList
是一个不好的选择,因为它不是线程安全的,并且在删除索引0
上的元素时,必须移至其右边的每个元素({ {1}}操作。
您要查找的集合称为O(n)
,也称为双端队列。但是,由于您需要集合具有线程安全性,因此我建议使用Deque
。
答案 1 :(得分:0)
我认为您将在这里使用LMAX Disruptor framework。我设想了两个RingBuffer。您将使用第一个接受传入的消息。您的工作人员将从RingBuffer中读取。您可以将RingBuffer的大小设置为等于您的持久块大小(例如100或1000)。工作者从RingBuffer接收事件并对其进行处理后,会将对持久对象的引用放置到Queue Collection中。每次第一个RingBuffer圈了一次,您就分配一个新的Queue,并将旧的Queue放入第二个RingBuffer。第二个RingBuffer的工作程序从RingBuffer中获取一个Queue对象,将所有对象保留在Queue中,然后移至下一个队列。您可以调整第二个RingBuffer和工作线程的大小,以适应数据库可以持久存储块的速度。
答案 2 :(得分:0)
使用这种方法可能会丢失消息,如果您收到100条消息但未保存,并且应用程序死了,您是否有能力丢失这些消息? 主题/队列的类型在这里很重要,主题具有管理此反压控制的优势,由于需要顺序处理,因此通常存在队列。 如果您排队/主题是kafka,并且您提取消息,kafka可以提取批次,并且您也可以将批次保存到数据库中,仅在保存消息后才将消息确认到kafka。 如果需要订购处理程序,则可以处理一些被动方法并调整数据库。通常,队列系统可以控制流量。