我有一个线程负责从 MySQL 数据库中清除旧数据。我们分批删除,因此如果有大量清除,则不会消耗数据库,因此线程执行清除,等待几秒钟,然后再次调用自身以继续清除(如果还有任何记录)。
我的问题是我们允许人们为需要清除的内容设置多个规则。在一个不批量执行任何操作的旧系统中,我们只需遍历每个“清除规则”并运行查询。
但是,现在我们有了一个线程再次自行调度的系统,我可以从中删除规则ArrayList
了,因为ConcurrentModificationException
我有一个ArrayList<QueryParameters>
我们迭代的。如果没有要清除的记录,我们应该从列表中删除规则,以便下次线程运行时不会重复它。
如何正确地从列表中删除规则但无法获得 CME?我想我可以使用 ConcurrentHashMap 但我不想真正想要存储键-> 值。
该代码是一个更大的 java 应用程序的插件,我们正在使用他们的线程调度程序,仅供参考。
我尝试了两种方法来迭代数组列表、for循环和使用迭代器
public class PurgeTask implements Runnable {
private Prism plugin;
private ArrayList<QueryParameters> paramList;
private int total_records_affected = 0, cycle_rows_affected = 0;
private int purge_tick_delay;
/**
*
* @param plugin
*/
public PurgeTask( Prism plugin, ArrayList<QueryParameters> paramList, int purge_tick_delay ){
this.plugin = plugin;
this.paramList = paramList;
this.purge_tick_delay = purge_tick_delay;
}
/**
*
*/
public void run(){
if(paramList.size() > 0){
ActionsQuery aq = new ActionsQuery(plugin);
// Execute in batches so we don't tie up the db with one massive query
for (Iterator<QueryParameters> it = paramList.iterator(); it.hasNext(); ) {
QueryParameters param = it.next();
cycle_rows_affected = aq.delete(param);
plugin.debug("Purge cycle cleared " + cycle_rows_affected + " rows.");
total_records_affected += cycle_rows_affected;
// If nothing (or less than the limit) has been deleted this cycle, we need to move on
if( cycle_rows_affected == 0 || cycle_rows_affected < plugin.getConfig().getInt("prism.purge.records-per-batch") ){
// Log final count of cleared records
plugin.log("Cleared " + total_records_affected + " rows from the database. Using:" + param.getOriginalCommand() );
total_records_affected = 0;
// Remove the purge rule from the list so we don't repeat
paramList.remove(param);
} else {
// Items we're deleted. Leave params in queue and re-schedule this task
plugin.deleteTask = plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, new PurgeTask( plugin, paramList, purge_tick_delay ), purge_tick_delay);
}
}
}
}
}