- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
当我在取消第一个计时器后启动第二个计时器时,我得到 ConcurrentModificationException
。两个计时器都使用单独的 ArrayList
并遍历它。没有对列表进行删除/修改,仍然抛出 ConcurrentModificationException
。
当我停止第一个计时器并立即启动第二个时,就会发生这种情况。如果我在启动第二个计时器之前等待几秒钟,那么它工作正常。
我最终在两个计时器上制作了传入列表的副本,将副本传递给计时器,但我仍然收到错误。不确定为什么,因为我正在遍历列表并仅读取值。
定时器 #1 的代码:
private void timerwork(final List<Object> list) throws IOException {
timer = new Timer();
final List<Object> taskList = list;
timer.scheduleAtFixedRate(new CustomTimerTask(taskList) {
@Override
public void run() {
if (taskList != null && !taskList.isEmpty()) {
synchronized (taskList) {
for (Object o: taskList) {
try {
// this method takes each object,
// does some logic and writes to a flat file,
// it does not modify the object itself,
// but just reads it and does some calculation
// on some local variables
valueIncrementOperation(o);
} catch (IOException e) {
timer.cancel();
timer.purge();
throw new RuntimeException(e.getMessage(), e);
}
}
//once exited out of the loop, it copies the flat file to another file
try {
copyFileUsingFileChannels(source, finaldest);
} catch (IOException ignore) {
}
}
}
public synchronized void valueIncrementOperation(Object o) throws IOException {
DataInputStream d = new DataInputStream(new FileInputStream(sourcefile));
DataOutputStream out = new DataOutputStream(new FileOutputStream(tempfile));
initialValue = Long.parseLong(o.getDefaullt_value());
String count;
String t;
while ((count = d.readLine()) != null) {
String u = count.toUpperCase();
String[] z = u.split(" ");
if (z[0].contains(o.getO())) {
// .............. *snip* ..............
out.writeBytes(t + "\n");
}
d.close();
out.close();
copyFileUsingFileChannels(source, initialDest);
}
CustomTimerTask 代码:
public class CustomTimerTask extends TimerTask {
private List<Object> list = new ArrayList<Object>();
public CustomTimerTask(List<Object> list) {
this.list = list;
}
@Override
public void run() {
// TODO Auto-generated method stub
}
}
计时器 2 具有类似的逻辑:即,它在传递给计时器 2 之前复制传入列表。
我仍然收到此错误:
Exception in thread "Timer-0" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:859)
at java.util.ArrayList$Itr.next(ArrayList.java:831)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
解决方法是在启动 timer2 之前等待几秒钟。有没有更好的方法来解决这种情况?
最佳答案
我们从堆栈跟踪中知道异常是从 ArrayList
内部抛出的。因此,让我们看一下处理 List
的代码行。 (为便于阅读,删除了多余的代码)
首先是方法调用:
private void timerwork(final List<Object> list) {
final List<Object> taskList = list;
这意味着 taskList
与传入的对象(称为 list
)完全相同。
其次,此 List
被传递到 CustomTimerTask
的构造函数中。
timer.scheduleAtFixedRate(new CustomTimerTask(taskList) {
第三,让我们检查一下构造函数:
private List<Object> list = new ArrayList<Object>();
public CustomTimerTask(List<Object> list) {
this.list = list;
}
所以你的 new ArrayList
被扔掉了,取而代之的是参数 list
,我们知道它是完全相同的对象传递给 timerwork()
。
我知道你说:
I ended up making a copy of the incoming list
但这在您发布的任何代码中都看不到。此外,我们不知道(因为您尚未发布)timerwork()
的调用代码,但可能它是这样的:
List<Object> list = ....
timerwork(list);
timerwork2(list);
如果是这样,那么我们会看到两个计时器任务在不同线程中对完全相同的对象 进行操作,这将解释 ConcurrentModificationException
。
在 CustomTimerTask
的构造函数中,即使我的诊断不正确,一个简单的修复也是一个好的做法:
private List<Object> list;
public CustomTimerTask(List<Object> list) {
// CustomTimerTask gets its own copy to play with
this.list = new ArrayList<Object>(list);
}
关于java - ConcurrentModificationException 定时器任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20291241/
哪种定时器在性能方面更适合使用? Jquery 计时器或 Javascript 计时器。 具有计时器的页面没有任何 Jquery 代码。 谢谢 最佳答案 在仅使用计时器的页面上引用完整的 JQuery
R 语言有没有简单的方法来设置定时器功能?计时器函数是指位于 session 后台并每隔一段时间执行一次的函数。 干杯! 最佳答案 tcltk2 包中有 tclTaskSchedule 函数(和其
我想在点击发生后调用 setTimeout()。 如果用户在 300ms 过去之前再次点击,我想停止那个计时器,触发另一个函数并重新启动原来的计时器。 我知道 setTimeout() 但我不确定如何
请参阅下面的代码...它会在页面加载 + 8 秒后更改图像,然后继续每 1 秒更改一次。 setInterval(function(){ setTimeout(function(){
我正在尝试使用计时器来安排应用程序中的重复事件。但是,我希望能够实时调整事件触发的时间段(根据用户输入)。 例如: public class HelperTimer extends TimerTask
setTimeout()--用于指定在一段特定的时间后执行某段程序。 格式: [定时
setTimeout 和 clearTimeout 复制代码 代码如下: var obj = setTimeout(cb, ms); setTim
if(e.getSource()==continuous) { TimerTask task = new TimerTask() { public void run()
请谁能告诉我如何在 iPhone 的 cocos2d 中实现启动游戏的倒计时器。 我的意思是,按下“播放”时,一个新场景会出现,显示数字“3”、“2”、“1”,然后显示“GO!”一词。 最佳答案 来自
我正在制作一个计时器,而且效果很好。唯一的问题是,每过一秒,它就会在新行中打印剩余的时间(以秒为单位)。我该如何做到这一点,而不是打印一个新行,而只是改变当前行中显示的内容? 这就是我所拥有的...
这个问题在这里已经有了答案: Lua Program Delay (2 个答案) 关闭 7 年前。 我目前使用 Corona SDK,Lua 作为我的主要语言。我在使用此代码时遇到问题 - 当我运行
我正在制作一个计时器,而且效果很好。唯一的问题是,每过一秒,它就会在新行中打印剩余的时间(以秒为单位)。我该如何做到这一点,而不是打印一个新行,而只是改变当前行中显示的内容? 这就是我所拥有的...
到目前为止,我使用的每种方法都只是暂时卡住我的程序,但我希望游戏继续运行,我只希望盾牌 boolean 值在 X 时间内为 true,然后在时间到期后返回 false,有吗有办法做到这一点吗?谢谢。
我需要创建一个异步线程,它运行一次,延迟 2 分钟,并且可以随时终止。我看到了几种可能的解决方案: ScheduledExecutorService 和 FutureTask 允许我中断正在运行的任务
我开发了一个简单的应用程序并使用了计时器,但如果我多次运行计时器,计时器会丢弃此异常:线程“AWT-EventQueue-0”java.lang.IllegalStateException 中的异常:
我正在实现一个计时器: timer = new Timer(); timer.schedule(new TimerTask() { @Overr
我有一个有点复杂的 iOS 用户界面,我需要每秒重新加载 UICollectionView 的特定单元格以显示时间(有点像复杂的秒表),我还需要每秒做一些其他事情在这次通话中。 问题的第 1 部分 我
我一直在研究可用于 QueryPerformanceCounter()/QueryPerformanceFrequency() 的不同类型的计时器,在进一步研究之后,我发现了一个使用计时器类的例子..
我正在尝试以微秒为单位做一个计时器,但它不太管用。 #include #include #include using namespace std; int main () { struc
假设我有一个整数数组 int timeouts [] = {1000 , 2000 , 3000 , 3500}; 我想创建一个计时器,最多计时 3.5 秒,并在毫秒计数等于数组元素之一时调用相同的函
我是一名优秀的程序员,十分优秀!