- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我运行一个服务器,它有一个处理计时系统的事件处理程序当我连续运行其中 3 个时,它给出了这个异常
Exception in thread "Thread-8" java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
at java.util.AbstractList$Itr.next(AbstractList.java:343)
at EventManager.run(EventManager.java:77)
at java.lang.Thread.run(Thread.java:662)
这是问题产生的方法:
EventManager.getSingleton().addEvent( new Event() {
public void execute(EventContainer c) {
p.createProjectile(p.absY, p.absX, offsetY, offsetX, 1166, 43, 31, 70, p2.playerId);
c.stop(); // stops the event from running
}
}, 950); // in ms (1 second = 1000 ms)
EventManager.getSingleton().addEvent( new Event() {
public void execute(EventContainer c) {
p2.applyDAMAGE(misc.random(25));
c.stop(); // stops the event from running
}
}, 1300); // in ms (1 second = 1000 ms)
p.secondsTillNextDfsSpecial = 120;
EventManager.getSingleton().addEvent( new Event() {
public void execute(EventContainer c) {
p.secondsTillNextDfsSpecial--;
if (p.secondsTillNextDfsSpecial == 0) {
p.canPerformDfsSpecial = true;
c.stop(); // stops the event from running
}
}
}, 1000); // in ms (1 second = 1000 ms)
import java.util.ArrayList;
import java.util.List;
/**
* Manages events which will be run in the future.
* Has its own thread since some events may need to be ran faster than the cycle time
* in the main thread.
*
* @author Graham
*
*/
public class EventManager implements Runnable {
/**
* A reference to the singleton;
*/
private static EventManager singleton = null;
/**
* A list of events that are being executed.
*/
private List<EventContainer> events;
/**
* Initialise the event manager.
*/
private EventManager() {
events = new ArrayList<EventContainer>();
}
/**
* The event manager thread. So we can interrupt it and end it nicely on shutdown.
*/
private Thread thread;
/**
* Gets the event manager singleton. If there is no singleton, the singleton is created.
* @return The event manager singleton.
*/
public static EventManager getSingleton() {
if(singleton == null) {
singleton = new EventManager();
singleton.thread = new Thread(singleton);
singleton.thread.start();
}
return singleton;
}
/**
* Initialises the event manager (if it needs to be).
*/
public static void initialise() {
getSingleton();
}
/**
* The waitFor variable is multiplied by this before the call to wait() is made.
* We do this because other events may be executed after waitFor is set (and take time).
* We may need to modify this depending on event count? Some proper tests need to be done.
*/
private static final double WAIT_FOR_FACTOR = 0.5;
@Override
/**
* Processes events. Works kinda like newer versions of cron.
*/
public synchronized void run() {
long waitFor = -1;
List<EventContainer> remove = new ArrayList<EventContainer>();
while(true) {
// reset wait time
waitFor = -1;
// process all events
for(EventContainer container : events) {
if(container.isRunning()) {
if((System.currentTimeMillis() - container.getLastRun()) >= container.getTick()) {
container.execute();
}
if(container.getTick() < waitFor || waitFor == -1) {
waitFor = container.getTick();
}
} else {
// add to remove list
remove.add(container);
}
}
// remove events that have completed
for(EventContainer container : remove) {
events.remove(container);
}
remove.clear();
// no events running
try {
if(waitFor == -1) {
wait(); // wait with no timeout
} else {
// an event is running, wait for that time or until a new event is added
int decimalWaitFor = (int)(Math.ceil(waitFor*WAIT_FOR_FACTOR));
wait(decimalWaitFor);
}
} catch(InterruptedException e) {
break; // stop running
}
}
}
/**
* Adds an event.
* @param event The event to add.
* @param tick The tick time.
*/
public synchronized void addEvent(Event event, int tick) {
events.add(new EventContainer(event,tick));
notify();
}
/**
* Shuts the event manager down.
*/
public void shutdown() {
this.thread.interrupt();
}
}</code></pre>
最佳答案
好的,我看到两个问题:
您的事件 List
未同步,您正在从不同的线程访问它(一个在 EventManager
中,第二个在带有 的第一段代码中) addEvent()
)。
在此循环中:
// process all events
for(EventContainer container : events) {
...
}
您正在迭代事件List
,并且在迭代时您无法向其中添加新元素。我假设 addEvent()
正在向此列表添加新元素,因此基本上您不应该在此迭代期间调用它。
这两个问题都可以通过使用 CopyOnWriteArrayList 来解决它允许并发线程安全访问并在迭代期间安全添加新元素(但是新元素仅在下一次迭代中“可见”)。
解决方案:
private EventManager() {
events = new CopyOnWriteArrayList() ;
}
关于java.util.AbstractList$Itr.checkForCommodification 三重事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5525787/
这个问题已经有答案了: Why we can't do List mylist = ArrayList(); [duplicate] (3 个回答) 已关闭 7 年前。 为什么 AbstractLis
这个问题已经有答案了: Access outer class from inner class: Why is it done this way? (3 个回答) Referencing an enc
是否可以以只能保存某种类型的对象的方式实现 AbstractList? 最佳答案 当然。 class FooList extends AbstractList { ... } 关于java - 是
在 RandomAccess 类的 java 文档中写道“List 实现使用的标记接口(interface)表明它们支持快速(通常是恒定时间)随机访问。此接口(interface)的主要目的是允许通用
在浏览 Effective Java 示例时,我无法理解下面的代码。这个匿名抽象类如何在不遍历数组元素或调用 add() 方法的情况下返回对象列表。 下面代码的幕后发生了什么? public
我有一个方法 foo(list); 这是一个 List 作为输入。 我的方法 foo 看起来有点像下面这样: public void foo(List
Android Studio 在 addAll() 方法内的 sort() 行上给我一个“Usage of API documented as @since 1.8+”错误。我不太确定这是什么意思..
List结构图 1.List public abstract interface List extends Collection 有序、允许有重复元素、值可为NULL。用户可以根据
我正在尝试学习 AbstractList 我发现有些方法总是抛出异常,我的问题是为什么要这样设计? /** * {@inheritDoc} * * This implementation al
我可以在文档中看到: java.util.AbstractList#removeRange 它需要二次时间: This implementation gets a list iterator posi
我在 Servlet 类中有以下代码,我得到 ConcurrentModificationException checkforcomodification at java.util.Abstractl
我运行一个服务器,它有一个处理计时系统的事件处理程序当我连续运行其中 3 个时,它给出了这个异常 Exception in thread "Thread-8" java.util.Concurrent
对于 AbstractList,哈希码计算如下: int hashCode = 1; Iterator i = list.iterator(); while (i.hasNext()) {
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
一边研究抽象类和接口(interface)。我确实想知道为什么 java 集合具有所有抽象类。为什么他们不实现接口(interface)而不是抽象类。我对 AbstractList,AbstractS
每当我尝试删除我的一个实体时,游戏都会给我这个错误,我不知道为什么。 这是产生错误的方法: public void render (Screen screen) { int xTile = 1
在我学习 C 语言的日子里,当我实现了一个 Queue 时,我在 LinkedList 之上实现了它们。所以基本上我有两个指针(前面和后面)用于 LinkedList 顶部的 Queue 操作,或者更
奇怪的是,AbstractList::equals() 的默认 JDK 6 实现 似乎没有首先检查两个列表是否具有相同的大小: public boolean equals(Object o) {
我正在阅读 openjdk AbstractList 的迭代器部分。我不明白检查 if (lastRet 这里,lastRet是next()最后返回的值的索引,cursor是next()要返回的值的索
Java AbstractList 类在您需要实现 List 接口(interface)时非常方便,而无需从头开始编写所有代码。 现在,在 C# 中,我需要在我的数据模型的一部分上实现一个 View
我是一名优秀的程序员,十分优秀!