【发布时间】:2014-10-03 16:53:30
【问题描述】:
我的一个应用程序通过读取数组 List 将对象绘制到屏幕上:
简单代码总结:
@Override
public synchronized void paintComponent(Graphics g) {
for(Object gO:paintList) {
g.drawImage( gO.getObjImage(), gO.getXLoc(), gO.getYLoc(), outer.getTransparent(), null);
}
}
问题是每次用户单击鼠标时我都会添加更多对象,因此如果用户单击速度足够快,我可能会导致程序绘制卡顿,因为它在写入时无法读取(arrayList 是同步的)。开发人员用于处理此并发问题的常见做法是什么?
编辑:这里是调用重绘的代码:
byte ticks = 0;
while(true) {
currentTime = System.nanoTime();
if(ticks == 25) {
drawPanel.repaint();
ticks = 0;
} else if (ticks%5 == 0) {//if ticks is a multiple of 5 (5,10,15,...)
drawPanel.operations();
ticks++;
} else if(ticks < 25) {
ticks++;
}
try {
/*
Refer to: 'http://stackoverflow.com/questions/1036754/difference-between-wait-and-sleep'
on differences between Thread.sleep() and wait()
*/
wait(1);//old timings: (long)(refreshRate*1000)
} catch (InterruptedException ex) {
Logger.getLogger(DeathWish.class.getName()).log(Level.SEVERE, null, ex);
}
//Debugging
//System.out.println(ticks);
currentTime = System.nanoTime();
*where operations() 计算“可绘制”对象属性的变化,删除满足特定条件的对象并将新对象添加到绘制列表中。从逻辑上讲,添加和写入应该分开吗? 如果没有足够的信息,我可以发布操作()方法,但我尽量不发布大量代码,以便更容易解释。
【问题讨论】:
-
一般来说,我有一个循环连续绘制屏幕,另一个循环处理任何事件(如单击以添加对象)。这样,如果事件处理程序卡在某个东西上,绘制循环将继续运行而不会卡顿。
-
我真的怀疑用户点击的速度是否比获得锁的速度更快。锁定获取时间约为 25ns。用户点击时间约为 50 毫秒。
-
你有什么例外吗?
-
@Dimitri 不,代码不会抛出任何异常,它曾经抛出 concurrentModificationException 但我不久前重组了代码。
-
您在@swap905 下方阅读我的评论了吗?我建议使用 CopyOnWriteArrayList
标签: java multithreading arraylist concurrency paintevent