gpt4 book ai didi

Java Paint 'stuttering' -列表并发

转载 作者:行者123 更新时间:2023-12-01 12:28:01 25 4
gpt4 key购买 nike

我的一个应用程序通过读取数组列表将对象绘制到屏幕上:

简单代码摘要:

@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();

*其中操作()计算“可绘制”对象属性的变化,删除满足特定条件的对象并将新对象添加到绘制列表中。从逻辑上讲,添加和写入应该分开吗?如果没有足够的信息,我可以发布操作()方法,但我尝试不发布大量代码,以便更容易解释。

最佳答案

我猜你在同步方面遇到了一些问题:

  • ArrayList是一个不同步实现的列表
  • 同步方法意味着一次只有 1 个线程可以访问该方法,但函数内的变量根本不同步

您想要的是暂时同步您的列表。

你可以做类似的事情:

@Override
public void paintComponent(Graphics g) {
synchronized(paintList) {
for(Object gO:paintList) {
g.drawImage( gO.getObjImage(), gO.getXLoc(), gO.getYLoc(), outer.getTransparent(), null);
}
}
}

在代码中添加对象到你的列表中做一些相同的事情。

从这里编辑:

如果您想消除添加线程和绘制线程之间的所有并发问题,可以这样做:

在添加图像的方法中:

public synchronized void addImage(...) {
Something newImage = .....
List<Something> newPaintList = new ArrayList<>(paintList.size() + 1);
newPaintList.addAll(paintList);
newPaintList.add(newImage);
paintList = newPaintList;
}

并在paint方法中,删除同步部分。

@Override
public void paintComponent(Graphics g) {
for(Object gO:paintList) {
g.drawImage( gO.getObjImage(), gO.getXLoc(), gO.getYLoc(), outer.getTransparent(), null);
}
}

这样,读取和写入之间就不会出现任何并发,因为对 PaintList 执行的唯一操作就是读取。

addImage应该同步以避免两个不同的线程同时添加图像,这可能会导致一个addImage被忽略。

关于Java Paint 'stuttering' -列表并发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26183287/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com