元素未从集合中移除

时间:2018-08-12 09:11:36

标签: java iterator set

我有一个带有比较器的TreeSet

private final TreeSet<TimedTask> sortedEvents;

public TimedUpdatableTaskList(){
    Comparator<TimedTask> comparator = new TimedTaskComparator();
    sortedEvents = new TreeSet<>(comparator);
}

该类实现了一种向集合中添加元素的方法:

public void add(TimedTask task) {
    synchronized (sortedEvents) {
        sortedEvents.add(task);
        log.info("Add task {}:{}", task.getClass().getName(), task);
    }
}

添加的TimedTask如下:

class AIRepairTask extends TimedTask {

    private AsyncEventBus clientServerEventBus;

    private final IShip ship;
    private final IShipyard shipyard;

    public AIRepairTask(LocalDateTime executionTime, IShip ship, IShipyard shipyard) {
        super();
        setExecutionTime(executionTime);
        this.ship = ship;
        this.shipyard = shipyard;
    }

    @Override
    public void run() {
        ship.repair();
        shipyard.removeCompletedRepair(ship);
        ship.setAvailable(true);
        clientServerEventBus.post(new RepairFinishedEvent(ship));
    }
}

然后有一种方法可以遍历元素并最终将其删除:

public void handleClockTick(ClockTick event) {
    LocalDateTime now = date.getCurrentDate();
    int nbHandledTasks = 0;
    synchronized (sortedEvents) {
        int initialSize = sortedEvents.size();
        boolean moreEvents = true;
        while(moreEvents && !sortedEvents.isEmpty()) {
            TimedTask task = sortedEvents.first();
            Preconditions.checkNotNull(task.getExecutionTime(), "The exectution time of the task may not be null");
            if (task.getExecutionTime().isBefore(now)) {
                try {
                    task.run();
                    boolean removed = sortedEvents.remove(task);
                    Preconditions.checkArgument(removed, "The Task "+task+" was not removed.");
                    nbHandledTasks++;
                } catch (Exception e) {
                    e.printStackTrace()
                }
            } else {
                moreEvents = false;
            }
        }
        Preconditions.checkArgument(initialSize - nbHandledTasks == sortedEvents.size(), "List size did not become smaller: initial size "+initialSize+", handled tasks "+nbHandledTasks+", actual list size: "+sortedEvents.size());
    }
}

由于基本部分都包裹在一个同步块中,因此在迭代元素时该集合不应更改。

考虑到try块中没有异常,最后的前提条件检查永远不会失败,但这就是发生的情况:

java.lang.IllegalArgumentException: List size did not become smaller: initial size 41, handled tasks 2, actual list size: 41

这怎么发生?

0 个答案:

没有答案